Mercurial > mm7
changeset 196:982c1ec5a983
More picking stuff
author | Nomad |
---|---|
date | Sat, 16 Feb 2013 20:24:02 +0200 |
parents | 3dfa006a6bef |
children | 5979fc0de9ae |
files | Vis.cpp Vis.h mm7_2.cpp mm7_data.h |
diffstat | 4 files changed, 234 insertions(+), 353 deletions(-) [+] |
line wrap: on
line diff
--- a/Vis.cpp Sat Feb 16 18:34:31 2013 +0200 +++ b/Vis.cpp Sat Feb 16 20:24:02 2013 +0200 @@ -23,29 +23,29 @@ //----- (004C1026) -------------------------------------------------------- -Vis_ObjectInfo *Vis::_4C1026(BLVFace *a2, unsigned int a3, float a4) +Vis_ObjectInfo *Vis::_4C1026(BLVFace *face, unsigned int a3, float pick_depth) { char *v4; // eax@4 signed int v5; // ecx@4 - BLVFace *v6; // ecx@7 - unsigned int v7; // edi@7 + //BLVFace *v6; // ecx@7 + //unsigned int v7; // edi@7 Vec3_short_ *v8; // eax@9 char *v9; // edx@9 signed int v10; // esi@10 - Vec3_int_ **v11; // edx@13 - char *v12; // eax@13 - double v13; // st7@14 - signed int v14; // ebx@14 - Vis *v15; // ebx@15 - Vis_ObjectInfo *result; // eax@21 - Vis_ObjectInfo *v17; // ecx@24 + //Vec3_int_ **v11; // edx@13 + //char *v12; // eax@13 + //double v13; // st7@14 + //signed int v14; // ebx@14 + //Vis *v15; // ebx@15 + //Vis_ObjectInfo *result; // eax@21 + //Vis_ObjectInfo *v17; // ecx@24 RenderVertexSoft pRay[2]; // [sp+20h] [bp-70h]@17 int v20; // [sp+84h] [bp-Ch]@10 - int v21; // [sp+88h] [bp-8h]@16 - int v22; // [sp+8Ch] [bp-4h]@16 + //int v21; // [sp+88h] [bp-8h]@16 + //int v22; // [sp+8Ch] [bp-4h]@16 signed int v23; // [sp+98h] [bp+8h]@7 - auto ecx0 = this; + //auto ecx0 = this; static Vis_SelectionList static_sub_4C1026_stru_F8FE00; static_sub_4C1026_stru_F8FE00.uNumPointers = 0; @@ -59,138 +59,150 @@ static_sub_4C1026_array_F8F200[i].flt_2C = 0.0f; } - v6 = a2; + //v6 = a2; v23 = 0; - v7 = v6->uNumVertices; - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) + //v7 = face->uNumVertices; + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) { - if ( (signed int)v7 > 0 ) + __debugbreak(); // refactor for BLV picking + if ( (signed int)face->uNumVertices > 0 ) { v8 = pIndoor->pVertices; v9 = (char *)&static_sub_4C1026_array_F8F200[0].vWorldPosition.y; do { v10 = v23++; - v20 = v8[v6->pVertexIDs[v10]].x; + v20 = v8[face->pVertexIDs[v10]].x; *((float *)v9 - 1) = (double)v20; - v20 = v8[v6->pVertexIDs[v10]].y; + v20 = v8[face->pVertexIDs[v10]].y; *(float *)v9 = (double)v20; v9 += 48; - v20 = v8[v6->pVertexIDs[v10]].z; + v20 = v8[face->pVertexIDs[v10]].z; *((float *)v9 - 11) = (double)v20; } - while ( v23 < (signed int)v7 ); + while ( v23 < (signed int)face->uNumVertices ); + } + } + else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) + { + uint bmodel_id = a3 >> 9; + auto v = (Vec3_int_ *)pOutdoor->pBModels[bmodel_id].pVertices.pVertices; + for (uint i = 0; i < face->uNumVertices; ++i) + { + static_sub_4C1026_array_F8F200[i].vWorldPosition.x = v[face->pVertexIDs[i]].x; + static_sub_4C1026_array_F8F200[i].vWorldPosition.y = v[face->pVertexIDs[i]].y; + static_sub_4C1026_array_F8F200[i].vWorldPosition.z = v[face->pVertexIDs[i]].z; } } - else - { - if ( (signed int)v7 > 0 ) - { - v11 = &pOutdoor->pBModels[a3 >> 9].pVertices.pVertices; - v12 = (char *)&static_sub_4C1026_array_F8F200[0].vWorldPosition.y; - do - { - *((float *)v12 - 1) = (double)(*v11)[v6->pVertexIDs[v23]].x; - v13 = (double)(*v11)[v6->pVertexIDs[v23]].y; - v14 = v23++; - *(float *)v12 = v13; - v12 += 48; - *((float *)v12 - 11) = (double)(*v11)[v6->pVertexIDs[v14]].z; - } - while ( v23 < (signed int)v7 ); - } - } - pGame->pIndoorCameraD3D->ViewTransform(static_sub_4C1026_array_F8F200, v7); - pGame->pIndoorCameraD3D->Project(static_sub_4C1026_array_F8F200, v7, 1); - v15 = this; - SortVectors_x(static_sub_4C1026_array_F8F200, 0, v7 - 1); - if ( static_sub_4C1026_array_F8F200[0].vWorldViewPosition.x > (double)a4 - || (_4C1495(static_sub_4C1026_array_F8F200, v7, (float *)&v21, (float *)&v22), - _4C12C3_FindSomeBillboard(static_sub_4C1026_array_F8F200, v7, *(float *)&v21, *(float *)&v22)) - || ((CastPickRay(pRay, *(float *)&v21, *(float *)&v22, a4), uCurrentlyLoadedLevelType != LEVEL_Indoor) ? PickOutdoor(a4, pRay, &static_sub_4C1026_stru_F8FE00, &vis_face_filter, 1) : PickIndoor(a4, pRay, &static_sub_4C1026_stru_F8FE00, &vis_face_filter), - (static_sub_4C1026_stru_F8FE00.create_object_pointers(Vis_SelectionList::All), - sort_object_pointers( - static_sub_4C1026_stru_F8FE00.object_pointers, - 0, - static_sub_4C1026_stru_F8FE00.uNumPointers - 1), - !static_sub_4C1026_stru_F8FE00.uNumPointers) - || (result = static_sub_4C1026_stru_F8FE00.sub_4C2551(2, a3)) == 0 - || (signed int)static_sub_4C1026_stru_F8FE00.uNumPointers > 1 - && ((signed int)static_sub_4C1026_stru_F8FE00.uNumPointers <= 0 ? (v17 = 0) : (v17 = static_sub_4C1026_stru_F8FE00.object_pointers[0]), - result != v17)) ) - result = 0; - return result; + else assert(false); + + pGame->pIndoorCameraD3D->ViewTransform(static_sub_4C1026_array_F8F200, face->uNumVertices); + pGame->pIndoorCameraD3D->Project(static_sub_4C1026_array_F8F200, face->uNumVertices, 1); + + //v15 = this; + SortVectors_x(static_sub_4C1026_array_F8F200, 0, face->uNumVertices - 1); + if (static_sub_4C1026_array_F8F200[0].vWorldViewPosition.x > pick_depth) + return nullptr; + + float screenspace_center_x, + screenspace_center_y; + GetPolygonScreenSpaceCenter(static_sub_4C1026_array_F8F200, face->uNumVertices, &screenspace_center_x, &screenspace_center_y); + if (IsPolygonOccludedByBillboard(static_sub_4C1026_array_F8F200, face->uNumVertices, screenspace_center_x, screenspace_center_y)) + return nullptr; + + CastPickRay(pRay, screenspace_center_x, screenspace_center_y, pick_depth); + + if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) + PickOutdoorFaces_Mouse(pick_depth, pRay, &static_sub_4C1026_stru_F8FE00, &vis_face_filter, true); + else if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + PickIndoorFaces_Mouse(pick_depth, pRay, &static_sub_4C1026_stru_F8FE00, &vis_face_filter); + else assert(false); + + static_sub_4C1026_stru_F8FE00.create_object_pointers(); + sort_object_pointers(static_sub_4C1026_stru_F8FE00.object_pointers, 0, static_sub_4C1026_stru_F8FE00.uNumPointers - 1); + if (!static_sub_4C1026_stru_F8FE00.uNumPointers) + return nullptr; + + if (!static_sub_4C1026_stru_F8FE00.sub_4C2551(2, a3)) + return nullptr; + + if (static_sub_4C1026_stru_F8FE00.uNumPointers) + return static_sub_4C1026_stru_F8FE00.object_pointers[0]; + else return nullptr; } // F91E08: using guessed type char static_sub_4C1026_byte_F91E08__init_flags; //----- (004C12C3) -------------------------------------------------------- -char Vis::_4C12C3_FindSomeBillboard(RenderVertexSoft *a1, int a2, float a3, float a4) +bool Vis::IsPolygonOccludedByBillboard(RenderVertexSoft *vertices, int num_vertices, float x, float y) { - signed int v5; // esi@1 - RenderBillboardD3D *v6; // edi@2 - double v7; // st7@9 - int v8; // edx@9 - RenderVertexSoft *v9; // ecx@10 - char result; // al@24 - Vis *thisa; // [sp+10h] [bp-8h]@1 - float thisb; // [sp+10h] [bp-8h]@9 - signed int v13; // [sp+14h] [bp-4h]@1 - float a3a; // [sp+28h] [bp+10h]@9 - float a4a; // [sp+2Ch] [bp+14h]@9 + //signed int v5; // esi@1 + //RenderBillboardD3D *v6; // edi@2 + //double v7; // st7@9 + //int v8; // edx@9 + //RenderVertexSoft *v9; // ecx@10 + //char result; // al@24 + //Vis *thisa; // [sp+10h] [bp-8h]@1 + //float thisb; // [sp+10h] [bp-8h]@9 + //signed int v13; // [sp+14h] [bp-4h]@1 + //float a3a; // [sp+28h] [bp+10h]@9 + //float a4a; // [sp+2Ch] [bp+14h]@9 - v13 = -1; - v5 = 0; - thisa = this; - if ( (signed int)pRenderer->uNumBillboardsToDraw <= 0 ) - { - return 0; - } - v6 = pRenderer->pBillboardRenderListD3D; - do - { - if ( IsPointInsideD3DBillboard(v6, a3, a4) - && (v13 == -1 - || (unsigned int)pBillboardRenderList[v6->uParentBillboardID].sZValue < pBillboardRenderList[pRenderer->pBillboardRenderListD3D[v13].uParentBillboardID].sZValue) ) - v13 = v5; - ++v5; - ++v6; - } - while ( v5 < (signed int)pRenderer->uNumBillboardsToDraw ); - if ( v13 == -1 ) + int v13 = -1; + //v5 = 0; + //thisa = this; + + //v6 = pRenderer->pBillboardRenderListD3D; + for (uint i = 0; i < pRenderer->uNumBillboardsToDraw; ++i) { - return 0; - } - v7 = 3.4028235e38; - v8 = a2; - a4a = 3.4028235e38; - a3a = -3.4028235e38; - thisb = -3.4028235e38; - if ( a2 > 0 ) - { - v9 = a1; - do + auto billboard = pRenderer->pBillboardRenderListD3D + i; + if (IsPointInsideD3DBillboard(billboard, x, y)) { - if ( v9->vWorldViewProjX < v7 ) - v7 = v9->vWorldViewProjX; - if ( v9->vWorldViewProjX > (double)a3a ) - a3a = v9->vWorldViewProjX; - if ( v9->vWorldViewProjY < (double)a4a ) - a4a = v9->vWorldViewProjY; - if ( v9->vWorldViewProjY > (double)thisb ) - thisb = v9->vWorldViewProjY; - ++v9; - --v8; + if (v13 == -1) + v13 = i; + else if ((unsigned int)pBillboardRenderList[billboard->uParentBillboardID].sZValue < pBillboardRenderList[pRenderer->pBillboardRenderListD3D[v13].uParentBillboardID].sZValue) + v13 = i; } - while ( v8 ); } - if ( v7 < pRenderer->pBillboardRenderListD3D[v13].pQuards[0].pos.x - || pRenderer->pBillboardRenderListD3D[v13].pQuards[0].pos.y > (double)a4a - || pRenderer->pBillboardRenderListD3D[v13].pQuards[3].pos.x < (double)a3a - || pRenderer->pBillboardRenderListD3D[v13].pQuards[1].pos.y < (double)thisb ) - result = 0; - else - result = 1; - return result; + + if ( v13 == -1 ) + return false; + + //v8 = num_vertices; + //v7 = 3.4028235e38; + float min_x = FLT_MAX; + //a4a = 3.4028235e38; + float min_y = FLT_MAX; + //a3a = -3.4028235e38; + float max_x = -FLT_MAX; + //thisb = -3.4028235e38; + float max_y = -FLT_MAX; + for (uint i = 0; i < num_vertices; ++i) + { + //v9 = a1; + //do + //{ + auto v = vertices + i; + + if (v->vWorldViewProjX < min_x) + min_x = v->vWorldViewProjX; + if (v->vWorldViewProjX > max_x) + max_x = v->vWorldViewProjX; + + if (v->vWorldViewProjY < min_y) + min_y = v->vWorldViewProjY; + if (v->vWorldViewProjY > max_y) + max_y = v->vWorldViewProjY; + //++v9; + //--v8; + //} + //while ( v8 ); + } + + if (min_x < pRenderer->pBillboardRenderListD3D[v13].pQuards[0].pos.x || pRenderer->pBillboardRenderListD3D[v13].pQuards[0].pos.y > min_y || + pRenderer->pBillboardRenderListD3D[v13].pQuards[3].pos.x < max_x || pRenderer->pBillboardRenderListD3D[v13].pQuards[1].pos.y < max_y) + return false; + + return true; } //----- (004C1417) -------------------------------------------------------- @@ -208,38 +220,21 @@ } //----- (004C1495) -------------------------------------------------------- -float *Vis::_4C1495(RenderVertexSoft *Src, int a2, float *a3, float *a4) +void Vis::GetPolygonScreenSpaceCenter(RenderVertexSoft *vertices, int num_vertices, float *out_center_x, float *out_center_y) { char *v5; // eax@2 signed int v6; // ecx@2 float *result; // eax@5 - Vis *thisa; // [sp+0h] [bp-4h]@1 - thisa = this; - - static bool static_sub_4C1495_byte_F8E9F8__init_flags = false; // weak static RenderVertexSoft static_sub_4C1495_array_F8DDF8[64]; - if ( !static_sub_4C1495_byte_F8E9F8__init_flags ) - { - static_sub_4C1495_byte_F8E9F8__init_flags = true; - for (uint i = 0; i < 64; ++i) - static_sub_4C1495_array_F8DDF8[i].flt_2C = 0.0f; - } + memcpy(static_sub_4C1495_array_F8DDF8, vertices, 48 * num_vertices); - memcpy(static_sub_4C1495_array_F8DDF8, Src, 48 * a2); - sort_objects_2(static_sub_4C1495_array_F8DDF8, 0, a2 - 1); - *a3 = (*(float *)&Vis_static_sub_4C1944_stru_F8BDE8.object_pointers[12 * a2 + 509] - - static_sub_4C1495_array_F8DDF8[0].vWorldViewProjX) - * 0.5 - + static_sub_4C1495_array_F8DDF8[0].vWorldViewProjX; - sort_objects_3(static_sub_4C1495_array_F8DDF8, 0, a2 - 1); - result = a4; - *a4 = (*(float *)&Vis_static_sub_4C1944_stru_F8BDE8.object_pointers[12 * a2 + 510] - - static_sub_4C1495_array_F8DDF8[0].vWorldViewProjY) - * 0.5 - + static_sub_4C1495_array_F8DDF8[0].vWorldViewProjY; - return result; + SortByScreenSpaceX(static_sub_4C1495_array_F8DDF8, 0, num_vertices - 1); + *out_center_x = (static_sub_4C1495_array_F8DDF8[num_vertices - 1].vWorldViewProjX - static_sub_4C1495_array_F8DDF8[0].vWorldViewProjX) * 0.5 + static_sub_4C1495_array_F8DDF8[0].vWorldViewProjX; + + SortByScreenSpaceY(static_sub_4C1495_array_F8DDF8, 0, num_vertices - 1); + *out_center_y = (static_sub_4C1495_array_F8DDF8[num_vertices - 1].vWorldViewProjY - static_sub_4C1495_array_F8DDF8[0].vWorldViewProjY) * 0.5 + static_sub_4C1495_array_F8DDF8[0].vWorldViewProjY; } //----- (004C1542) -------------------------------------------------------- @@ -330,7 +325,7 @@ } //----- (004C16B4) -------------------------------------------------------- -void Vis::PickIndoor(float fDepth, RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter) +void Vis::PickIndoorFaces_Mouse(float fDepth, RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter) { int v5; // eax@1 signed int v6; // edi@2 @@ -347,6 +342,8 @@ int v17; // [sp+48h] [bp-8h]@1 Vis *thisa; // [sp+4Ch] [bp-4h]@1 + __debugbreak(); // refactor for BLV picking + v5 = 0; thisa = this; v17 = 0; @@ -388,99 +385,40 @@ } //----- (004C17CF) -------------------------------------------------------- -void Vis::PickOutdoor(float fDepth, RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter, char a6) -{ - int v6; // esi@1 - unsigned int v7; // ecx@1 - BSPModel *v8; // ebx@3 - bool v9; // eax@3 - int v10; // eax@8 - ODMFace *v11; // esi@10 - int v12; // ecx@12 - int v13; // eax@12 - unsigned int *pNumPointers; // eax@12 - Vis_ObjectInfo *v15; // edi@12 - BLVFace thisa; // [sp+10h] [bp-B8h]@1 - RenderVertexSoft a1; // [sp+70h] [bp-58h]@1 - void *v18; // [sp+A0h] [bp-28h]@12 - void *v19; // [sp+A4h] [bp-24h]@12 - int v20; // [sp+A8h] [bp-20h]@12 - int v21; // [sp+ACh] [bp-1Ch]@8 - Vis *v22; // [sp+B0h] [bp-18h]@1 - int v23; // [sp+B4h] [bp-14h]@9 - int v24; // [sp+B8h] [bp-10h]@1 - unsigned int v25; // [sp+BCh] [bp-Ch]@2 - unsigned int v26; // [sp+C0h] [bp-8h]@1 - int v27; // [sp+C4h] [bp-4h]@8 - - v22 = this; - v6 = 0; - v7 = 0; - v24 = 0; - v26 = 0; - a1.flt_2C = 0.0; +void Vis::PickOutdoorFaces_Mouse(float fDepth, RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter, bool one_sided) +{ if (!pOutdoor) return; - if ( (signed int)pOutdoor->uNumBModels > 0 ) + + for (uint i = 0; i < pOutdoor->uNumBModels; ++i) { - v25 = 0; - do + int v24; + if (!IsBModelVisible(i, &v24)) + continue; + if (one_sided && !v24) + continue; + + auto bmodel = &pOutdoor->pBModels[i]; + + for (uint j = 0; j < bmodel->uNumFaces; ++j) { - v8 = &pOutdoor->pBModels[v25 / 0xBC]; - v9 = IsBModelVisible(v7, &v24); - if ( a6 ) + auto face = bmodel->pFaces + j; + if (is_part_of_selection(face, filter)) { - if ( v9 && v24 != v6 ) + BLVFace blv_face; + blv_face.FromODM(face); + + RenderVertexSoft intersection; + if (Intersect_Ray_Face(pRay, pRay + 1, &fDepth, &intersection, &blv_face, i)) { -LABEL_8: - v10 = v8->uNumFaces; - v27 = v6; - v21 = v10; - if ( v10 > v6 ) - { - v23 = v6; - do - { - v11 = (ODMFace *)((char *)v8->pFaces + v23); - if ( is_part_of_selection((BLVFace *)((char *)v8->pFaces + v23), filter) ) - { - thisa.FromODM(v11); - if ( Intersect_Ray_Face(pRay, pRay + 1, &fDepth, &a1, &thisa, v26) ) - { - pGame->pIndoorCameraD3D->ViewTransform(&a1, 1u); - v18 = v11; - v13 = _48B561_mess_with_scaling_along_z(/*v12, */a1.vWorldViewPosition.x); - LOWORD(v13) = 0; - v20 = 2; - v19 = (void *)((8 * (v27 | (v26 << 6)) | 6) + v13); - pNumPointers = &list->uNumPointers; - v15 = &list->object_pool[list->uNumPointers]; - v15->object = v18; - v15 = (Vis_ObjectInfo *)((char *)v15 + 4); - v15->object = v19; - v15->sZValue = v20; - ++*pNumPointers; - } - } - ++v27; - v23 += 308; - } - while ( v27 < v21 ); - v6 = 0; - } - goto LABEL_15; + pGame->pIndoorCameraD3D->ViewTransform(&intersection, 1u); + int v13 = _48B561_mess_with_scaling_along_z(/*v12, */intersection.vWorldViewPosition.x); + LOWORD(v13) = (8 * (j | (i << 6)) | OBJECT_BModel) + v13; + + list->AddObject(face, VisObjectType_Face, v13); } } - else - { - if ( v9 ) - goto LABEL_8; - } -LABEL_15: - v25 += 188; - v7 = v26++ + 1; } - while ( (signed int)v26 < (signed int)pOutdoor->uNumBModels ); } } @@ -509,7 +447,7 @@ Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers = 0; v6 = (double)a3; v8.object_type = VisObjectType_Sprite; - PickBillboards_All(v6, &Vis_static_sub_4C1944_stru_F8BDE8, &v8); + PickBillboards_Keyboard(v6, &Vis_static_sub_4C1944_stru_F8BDE8, &v8); Vis_static_sub_4C1944_stru_F8BDE8.create_object_pointers(Vis_SelectionList::Unique); sort_object_pointers( Vis_static_sub_4C1944_stru_F8BDE8.object_pointers, @@ -1161,6 +1099,7 @@ object_pointers[i] = &object_pool[i]; } } + break; default: MessageBoxW(nullptr, L"Unknown pointer creation flag passed to ::create_object_pointers()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:1358", 0); @@ -1350,7 +1289,7 @@ } //----- (004C288E) -------------------------------------------------------- -bool Vis::sort_objects_2(RenderVertexSoft *pArray, int sLeft, int sRight) +bool Vis::SortByScreenSpaceX(RenderVertexSoft *pArray, int sLeft, int sRight) { bool result; // eax@1 RenderVertexSoft *v5; // edx@2 @@ -1365,11 +1304,11 @@ //float v13; // [sp+4Ch] [bp-24h]@4 int v14; // [sp+64h] [bp-Ch]@7 //Vis *thisa; // [sp+68h] [bp-8h]@1 - void *thisa; + //void *thisa; //RenderVertexSoft *v16; // [sp+6Ch] [bp-4h]@2 const void *v16; - thisa = this; + //thisa = this; if (sRight <= sLeft) return true; v5 = pArray; @@ -1404,13 +1343,13 @@ memcpy(&v11, &v5[v6], sizeof(v11)); memcpy(&v5[v6], v16, sizeof(v5[v6])); memcpy((void *)v16, &v11, sizeof(0x30u)); - sort_objects_2(v5, sLeft, v6 - 1); - sort_objects_2(pArray, v6 + 1, sRight); + SortByScreenSpaceX(v5, sLeft, v6 - 1); + SortByScreenSpaceX(pArray, v6 + 1, sRight); return true; } //----- (004C297E) -------------------------------------------------------- -bool Vis::sort_objects_3(RenderVertexSoft *pArray, int sLeft, int sRight) +bool Vis::SortByScreenSpaceY(RenderVertexSoft *pArray, int sLeft, int sRight) { //bool result; // eax@1 RenderVertexSoft *v5; // edx@2 @@ -1462,8 +1401,8 @@ memcpy(&v11, &v5[v6], sizeof(0x30)); memcpy(&v5[v6], v16, sizeof(v5[v6])); memcpy((void *)v16, &v11, sizeof(0x30)); - sort_objects_3(v5, sLeft, v6 - 1); - sort_objects_3(pArray, v6 + 1, sRight); + SortByScreenSpaceY(v5, sLeft, v6 - 1); + SortByScreenSpaceY(pArray, v6 + 1, sRight); return true; } @@ -1471,12 +1410,9 @@ //----- (004C04AF) -------------------------------------------------------- Vis::Vis() { - Vis *v1; // ebx@1 - Vis *result; // eax@1 RenderVertexSoft v3; // [sp+Ch] [bp-60h]@1 RenderVertexSoft v4; // [sp+3Ch] [bp-30h]@1 - v1 = this; v3.flt_2C = 0.0; v3.vWorldPosition.x = 0.0; v3.vWorldPosition.y = 65536.0; @@ -1485,20 +1421,22 @@ v4.vWorldPosition.x = 65536.0; v4.vWorldPosition.y = 0.0; v4.vWorldPosition.z = 0.0; - memcpy(&v1->stru_200C, &v4, sizeof(v1->stru_200C)); + memcpy(&stru_200C, &v4, sizeof(stru_200C)); + v4.flt_2C = 0.0; v4.vWorldPosition.x = 0.0; v4.vWorldPosition.y = 65536.0; v4.vWorldPosition.z = 0.0; - memcpy(&v1->stru_203C, &v3, sizeof(v1->stru_203C)); + memcpy(&stru_203C, &v3, sizeof(stru_203C)); + v3.flt_2C = 0.0; v3.vWorldPosition.x = 65536.0; v3.vWorldPosition.y = 0.0; v3.vWorldPosition.z = 0.0; - memcpy(&v1->stru_206C, &v3, sizeof(v1->stru_206C)); - result = v1; - memcpy(&v1->stru_209C, &v4, sizeof(v1->stru_209C)); - v1->field_20CC = 512; + memcpy(&stru_206C, &v3, sizeof(stru_206C)); + memcpy(&stru_209C, &v4, sizeof(stru_209C)); + + keyboard_pick_depth = 512; } //----- (004C055C) -------------------------------------------------------- @@ -1520,11 +1458,11 @@ list = &default_list; list->uNumPointers = 0; - PickBillboards_All(field_20CC, list, face_filter); + PickBillboards_Keyboard(keyboard_pick_depth, list, sprite_filter); if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - _4C0D32_KeyboardPickFaces_BLV(field_20CC, list, face_filter); + PickIndoorFaces_Keyboard(keyboard_pick_depth, list, face_filter); else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) - _4C0DEA_KeyboardPickFaces_ODM(field_20CC, list, face_filter); + PickOutdoorFaces_Keyboard(keyboard_pick_depth, list, face_filter); else assert(false); @@ -1543,9 +1481,9 @@ CastPickRay(pMouseRay, fMouseX, fMouseY, fDepth); PickBillboards_Mouse(fDepth, fMouseX, fMouseY, &default_list, sprite_filter); if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - PickIndoor(fDepth, pMouseRay, &default_list, face_filter); + PickIndoorFaces_Mouse(fDepth, pMouseRay, &default_list, face_filter); else - PickOutdoor(fDepth, pMouseRay, &default_list, face_filter, 0); + PickOutdoorFaces_Mouse(fDepth, pMouseRay, &default_list, face_filter, false); default_list.create_object_pointers(Vis_SelectionList::All); sort_object_pointers(default_list.object_pointers, 0, default_list.uNumPointers - 1); @@ -1553,7 +1491,7 @@ } //----- (004C06F8) -------------------------------------------------------- -void Vis::PickBillboards_All(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter) +void Vis::PickBillboards_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter) { for (int i = 0; i < pRenderer->uNumBillboardsToDraw; ++i) { @@ -1735,9 +1673,9 @@ GetPolygonCenter(pRenderer->pBillboardRenderListD3D[v3].pQuards, 4, (float *)&v35, (float *)&v36); CastPickRay(pPickingRay, *(float *)&v35, *(float *)&v36, fDepth); if (uCurrentlyLoadedLevelType == LEVEL_Indoor) - PickIndoor(fDepth, pPickingRay, &Vis_static_stru_F91E10, &vis_face_filter); + PickIndoorFaces_Mouse(fDepth, pPickingRay, &Vis_static_stru_F91E10, &vis_face_filter); else - PickOutdoor(fDepth, pPickingRay, &Vis_static_stru_F91E10, &vis_face_filter, 0); + PickOutdoorFaces_Mouse(fDepth, pPickingRay, &Vis_static_stru_F91E10, &vis_face_filter, false); Vis_static_stru_F91E10.create_object_pointers(); sort_object_pointers(Vis_static_stru_F91E10.object_pointers, 0, Vis_static_stru_F91E10.uNumPointers - 1); if (Vis_static_stru_F91E10.uNumPointers) @@ -1771,9 +1709,9 @@ v15 = v12; CastPickRay(local_80, SLODWORD(v15), v14, fDepth); if ( uCurrentlyLoadedLevelType == 1 ) - PickIndoor(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter); + PickIndoorFaces_Mouse(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter); else - PickOutdoor(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter, 0); + PickOutdoorFaces_Mouse(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter, false); Vis_static_stru_F91E10.create_object_pointers(); sort_object_pointers(Vis_static_stru_F91E10.object_pointers, 0, Vis_static_stru_F91E10.uNumPointers - 1); if ( !Vis_static_stru_F91E10.uNumPointers ) @@ -1818,8 +1756,8 @@ || (double)pViewport->uScreenY > v41 || (double)pViewport->uScreenW < v41 || ((v25 = v23, CastPickRay(local_80, SLODWORD(v25), v41, fDepth), uCurrentlyLoadedLevelType != 1) ? - (PickOutdoor(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter, 0)) : - (PickIndoor(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter)), + (PickOutdoorFaces_Mouse(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter, false)) : + (PickIndoorFaces_Mouse(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter)), (Vis_static_stru_F91E10.create_object_pointers(), sort_object_pointers(Vis_static_stru_F91E10.object_pointers, 0, Vis_static_stru_F91E10.uNumPointers - 1), Vis_static_stru_F91E10.uNumPointers) @@ -1836,7 +1774,7 @@ // F93E18: using guessed type char static_byte_F93E18_init; //----- (004C0D32) -------------------------------------------------------- -int Vis::_4C0D32_KeyboardPickFaces_BLV(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter) +void Vis::PickIndoorFaces_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter) { int result; // eax@1 signed int v5; // esi@2 @@ -1874,88 +1812,33 @@ } result = i + 1; } - return result; } //----- (004C0DEA) -------------------------------------------------------- -void Vis::_4C0DEA_KeyboardPickFaces_ODM(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter) +void Vis::PickOutdoorFaces_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter) { - int v4; // esi@1 - BSPModel *v5; // ebx@3 - unsigned __int8 v6; // zf@5 - char v7; // sf@5 - unsigned __int8 v8; // of@5 - ODMFace *v9; // esi@7 - unsigned int v10; // eax@8 - Vis_ObjectInfo *v11; // eax@8 - //unsigned int v12; // ecx@9 - BLVFace f; // [sp+10h] [bp-84h]@1 - //void *v14; // [sp+70h] [bp-24h]@9 - //int v15; // [sp+74h] [bp-20h]@9 - //unsigned int v16; // [sp+78h] [bp-1Ch]@9 - int v17; // [sp+7Ch] [bp-18h]@1 - Vis *v18; // [sp+80h] [bp-14h]@1 - int v19; // [sp+84h] [bp-10h]@6 - unsigned int v20; // [sp+88h] [bp-Ch]@2 - int v21; // [sp+8Ch] [bp-8h]@5 - int a1; // [sp+90h] [bp-4h]@1 + for (uint i = 0; i < pOutdoor->uNumBModels; ++i) + { + int v17; + if (!IsBModelVisible(i, &v17)) + continue; + if (!v17) + continue; - auto ecx0 = this; - v18 = ecx0; - v4 = 0; - v17 = 0; - a1 = 0; - if ( (signed int)pOutdoor->uNumBModels > 0 ) - { - v20 = 0; - do + auto bmodel = pOutdoor->pBModels + i; + for (uint j = 0; j < bmodel->uNumFaces; ++j) { - v5 = &pOutdoor->pBModels[v20 / 0xBC]; - if ( IsBModelVisible(a1, &v17) ) + auto face = bmodel->pFaces + j; + + if (is_part_of_selection(face, filter) ) { - if ( v17 != v4 ) - { - v8 = __OFSUB__(v5->uNumFaces, v4); - v6 = v5->uNumFaces == v4; - v7 = ((v5->uNumFaces - v4) & 0x80000000u) != 0; - v21 = v4; - if ( !((unsigned __int8)(v7 ^ v8) | v6) ) - { - v19 = v4; - do - { - v9 = (ODMFace *)((char *)v5->pFaces + v19); - if ( is_part_of_selection((BLVFace *)((char *)v5->pFaces + v19), filter) ) - { - f.FromODM(v9); - v10 = 8 * (v21 | (a1 << 6)); - LOBYTE(v10) = v10 | OBJECT_BModel; - v11 = _4C1026(&f, v10, pick_depth); - if ( v11 ) - { - /*v14 = v11->object; - v15 = v11->sZValue; - v12 = a3->uNumPointers; - //v16 = v11->uObjectType; - v12 *= 3; - *((int *)&a3->object_pool[0].object + v12) = (int)v14; - *(&a3->object_pool[0].sZValue + v12) = v15; - *(&a3->object_pool[0].object_type + v12) = v11->object_type; - ++a3->uNumPointers;*/ - list->AddObject(v11->object, v11->object_type, v11->sZValue); - } - } - ++v21; - v19 += 308; - } - while ( v21 < (signed int)v5->uNumFaces ); - v4 = 0; - } - } + BLVFace blv_face; + blv_face.FromODM(face); + + int pid = 8 * (j | (i << 6)) | OBJECT_BModel; + if (auto object_info = _4C1026(&blv_face, pid, pick_depth)) + list->AddObject(object_info->object, object_info->object_type, object_info->sZValue); } - ++a1; - v20 += 188; } - while ( a1 < (signed int)pOutdoor->uNumBModels ); } } \ No newline at end of file
--- a/Vis.h Sat Feb 16 18:34:31 2013 +0200 +++ b/Vis.h Sat Feb 16 20:24:02 2013 +0200 @@ -89,20 +89,22 @@ //----- (004C05BE) -------------------------------------------------------- ~Vis() {} bool PickKeyboard(Vis_SelectionList *list, Vis_SelectionFilter *sprite_filter, Vis_SelectionFilter *face_filter); + void PickBillboards_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter); + void PickIndoorFaces_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter); + void PickOutdoorFaces_Keyboard(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter); + bool PickMouse(float fDepth, float fMouseX, float fMouseY, Vis_SelectionFilter *sprite_filter, Vis_SelectionFilter *face_filter); void PickBillboards_Mouse(float fPickDepth, float fX, float fY, Vis_SelectionList *list, Vis_SelectionFilter *filter); - void PickBillboards_All(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter); + void PickIndoorFaces_Mouse(float fDepth, struct RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter); + void PickOutdoorFaces_Mouse(float fDepth, struct RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter, bool one_sided); + bool is_part_of_selection(void *uD3DBillboardIdx_or_pBLVFace_or_pODMFace, Vis_SelectionFilter *filter); bool DoesRayIntersectBillboard(float fDepth, unsigned int uD3DBillboardIdx); - int _4C0D32_KeyboardPickFaces_BLV(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter); - void _4C0DEA_KeyboardPickFaces_ODM(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter); - Vis_ObjectInfo *_4C1026(struct BLVFace *a2, unsigned int a3, float a4); - char _4C12C3_FindSomeBillboard(struct RenderVertexSoft *a1, int a2, float a3, float a4); + Vis_ObjectInfo *_4C1026(struct BLVFace *face, unsigned int a3, float pick_depth); + bool IsPolygonOccludedByBillboard(struct RenderVertexSoft *vertices, int num_vertices, float x, float y); void GetPolygonCenter(struct RenderVertexD3D3 *pVertices, unsigned int uNumVertices, float *pCenterX, float *pCenterY); - float *_4C1495(struct RenderVertexSoft *Src, int a2, float *a3, float *a4); + void GetPolygonScreenSpaceCenter(struct RenderVertexSoft *vertices, int num_vertices, float *out_center_x, float *out_center_y); bool IsPointInsideD3DBillboard(struct RenderBillboardD3D *a1, float x, float y); - void PickIndoor(float fDepth, struct RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter); - void PickOutdoor(float fDepth, struct RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter, char a6); int _4C1944(int object_id, unsigned int a3, int a4, int a5, int a6); void _4C1A02(); bool SortVectors_x(RenderVertexSoft *a2, int a3, int a4); @@ -116,8 +118,8 @@ void sort_object_pointers(Vis_ObjectInfo **pPointers, int left, int right); bool SortVerticesByX(struct RenderVertexD3D3 *a2, unsigned int uStart, unsigned int uEnd); bool SortVerticesByY(struct RenderVertexD3D3 *a2, unsigned int uStart, unsigned int uEnd); - bool sort_objects_2(struct RenderVertexSoft *pArray, int sLeft, int sRight); - bool sort_objects_3(struct RenderVertexSoft *pArray, int sLeft, int sRight); + bool SortByScreenSpaceX(struct RenderVertexSoft *pArray, int sLeft, int sRight); + bool SortByScreenSpaceY(struct RenderVertexSoft *pArray, int sLeft, int sRight); void (__thiscall ***vdestructor_ptr)(Vis *, bool); Vis_SelectionList default_list; @@ -125,6 +127,6 @@ RenderVertexSoft stru_203C; RenderVertexSoft stru_206C; RenderVertexSoft stru_209C; - int field_20CC; + int keyboard_pick_depth; }; #pragma pack(pop)
--- a/mm7_2.cpp Sat Feb 16 18:34:31 2013 +0200 +++ b/mm7_2.cpp Sat Feb 16 20:24:02 2013 +0200 @@ -15205,7 +15205,7 @@ } //----- (0046A14B) -------------------------------------------------------- -char __cdecl OnPressSpace() +void OnPressSpace() { //SHORT v0; // ax@2 int *v1; // eax@2 @@ -15235,8 +15235,7 @@ pGame->PickKeyboard(GetAsyncKeyState(VK_CONTROL) & 0x8001, &vis_sprite_filter_3, &vis_door_filter); v1 = (int *)pGame->pVisInstance->get_picked_object_zbuf_val(); if ( v1 != (int *)-1 ) - LOBYTE(v1) = DoInteractionWithTopmostZObject((unsigned __int16)v1, (signed int)(unsigned __int16)v1 >> 3); - return (char)v1; + DoInteractionWithTopmostZObject((unsigned __int16)v1, (signed int)(unsigned __int16)v1 >> 3); } v22 = 0; v1 = (int *)((signed int)(viewparams->uScreenZ + viewparams->uScreenX) >> 1); @@ -15333,10 +15332,7 @@ if ( !(char)v1 ) break; } - return (char)v1; -} -// 72065C: using guessed type int dword_72065C[]; -// 7207EC: using guessed type int dword_7207EC[]; +} //----- (0046A334) -------------------------------------------------------- char __fastcall DoInteractionWithTopmostZObject(int a1, int a2)
--- a/mm7_data.h Sat Feb 16 18:34:31 2013 +0200 +++ b/mm7_data.h Sat Feb 16 20:24:02 2013 +0200 @@ -2145,7 +2145,7 @@ void __cdecl OnPaperdollLeftClick(); int __thiscall UnprojectX(int x); int __thiscall UnprojectY(int _this); -char __cdecl OnPressSpace(); +void OnPressSpace(); char __fastcall DoInteractionWithTopmostZObject(int a1, int a2); int __fastcall sub_46A6AC(int a1, int a2, int a3); int __fastcall sub_46A7C8(int a1, int a2, signed int a3);