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