Mercurial > mm7
diff mm7_4.cpp @ 138:a8ec7e1e18b6
Sliding downhill & relative subs.
how it's done: each time you get a little bit pushed in the air along terrain normal,
and then falling to the gravity, gradually sliding downwards. nice trick
author | Nomad |
---|---|
date | Tue, 12 Feb 2013 00:22:30 +0200 |
parents | 9b0d651821f1 |
children | cca78efb377e 77ad59c17864 |
line wrap: on
line diff
--- a/mm7_4.cpp Mon Feb 11 20:27:00 2013 +0200 +++ b/mm7_4.cpp Tue Feb 12 00:22:30 2013 +0200 @@ -977,118 +977,80 @@ return dword_720F20[v22]; } + +//not sure if right- or left-handed coordinate space assumed, so this could be normal of inverse normal +// for a right-handed system, that would be an inverse normal //----- (0046DCC8) -------------------------------------------------------- -signed __int64 __fastcall _46DCC8_get_gravity_direction_outdoor(int a1, int a2, Vec3_int_ *a3) -{ - int v3; // ebx@1 - int v4; // ST4C_4@1 - unsigned int v5; // ST54_4@1 - unsigned int v6; // edi@1 - unsigned int v7; // ST50_4@1 - int v8; // edi@1 - int v9; // esi@1 - int v10; // ebx@1 - int v11; // ecx@2 - int v12; // eax@2 - int v13; // edx@2 - int v14; // ebx@2 - double v15; // st7@4 - double v16; // st6@4 - double v17; // st5@4 - float v18; // ST44_4@4 - float v19; // ST54_4@4 - double v20; // st4@4 - double v21; // st5@4 - float v22; // ST44_4@6 - double v23; // st7@4 - double v24; // st7@6 - signed __int64 result; // qax@6 - int v26; // [sp+14h] [bp-44h]@1 - int v27; // [sp+18h] [bp-40h]@1 - int v28; // [sp+20h] [bp-38h]@1 - int v29; // [sp+24h] [bp-34h]@1 - int v30; // [sp+28h] [bp-30h]@1 - int v31; // [sp+2Ch] [bp-2Ch]@1 - int v32; // [sp+30h] [bp-28h]@1 - int v33; // [sp+34h] [bp-24h]@1 - int v34; // [sp+38h] [bp-20h]@1 - int v35; // [sp+3Ch] [bp-1Ch]@1 - int v36; // [sp+40h] [bp-18h]@1 - int v37; // [sp+4Ch] [bp-Ch]@2 - float v38; // [sp+4Ch] [bp-Ch]@4 - int v39; // [sp+50h] [bp-8h]@2 - float v40; // [sp+50h] [bp-8h]@4 - int v41; // [sp+54h] [bp-4h]@2 - - v3 = a1; - v4 = a2; - v5 = WorldPosToGridCellX(a1); - v6 = WorldPosToGridCellZ(v4) - 1; - v33 = GridCellToWorldPosX(v5); - v34 = GridCellToWorldPosX(v5 + 1); - v35 = GridCellToWorldPosX(v5 + 1); - v36 = GridCellToWorldPosX(v5); - v29 = GridCellToWorldPosZ(v6); - v30 = GridCellToWorldPosZ(v6); - v7 = v6 + 1; - v31 = GridCellToWorldPosZ(v6 + 1); - v32 = GridCellToWorldPosZ(v6 + 1); - v26 = pOutdoor->DoGetHeightOnTerrain(v5, v6); - v27 = pOutdoor->DoGetHeightOnTerrain(v5 + 1, v6); - v8 = pOutdoor->DoGetHeightOnTerrain(v5 + 1, v6 + 1); - v28 = pOutdoor->DoGetHeightOnTerrain(v5, v7); - v9 = v29; - v10 = abs(v3 - v33); - if ( abs(v29 - v4) >= v10 ) - { - v11 = v33; - v37 = v28; - v39 = v36; - v12 = v35; - v41 = v32; - v13 = v31; - v14 = v8; - v8 = v26; - } - else - { - v11 = v35; - v41 = v30; - v39 = v34; - v12 = v33; - v13 = v29; - v9 = v31; - v37 = v27; - v14 = v26; - } - v15 = (double)(v12 - v39); - v16 = (double)(v13 - v41); - v17 = (double)(v14 - v37); - v18 = (double)(v11 - v39); - v19 = (double)(v9 - v41); - v20 = (double)(v8 - v37); - v38 = v20 * v16 - v19 * v17; - v40 = v18 * v17 - v20 * v15; - v21 = v19 * v15 - v18 * v16; - v23 = sqrt(v21 * v21 + v40 * v40 + v38 * v38); - if ( v23 == 0.0 ) - { - a3->y = 0; - a3->x = 0; - a3->z = 65536; - } - v24 = 1.0 / v23; - a3->x = (signed __int64)(v24 * v38 * 65536.0); - a3->y = (signed __int64)(v24 * v40 * 65536.0); - v22 = v21; - result = (signed __int64)(v24 * v22 * 65536.0); - a3->z = result; - return result; -} -// 47F44B: using guessed type int __stdcall WorldPosToGridCellX(int); -// 47F458: using guessed type int __stdcall WorldPosToGridCellZ(int); -// 47F469: using guessed type int __stdcall GridCellToWorldPosX(int); -// 47F476: using guessed type int __stdcall GridCellToWorldPosZ(int); +void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out) +{ + auto grid_x = WorldPosToGridCellX(pos_x); + auto grid_z = WorldPosToGridCellZ(pos_z) - 1; + + auto grid_pos_x1 = GridCellToWorldPosX(grid_x); + auto grid_pos_x2 = GridCellToWorldPosX(grid_x + 1); + auto grid_pos_z1 = GridCellToWorldPosZ(grid_z); + auto grid_pos_z2 = GridCellToWorldPosZ(grid_z + 1); + + auto x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z); + auto x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z); + auto x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1); + auto x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); + + float side1_dx, side1_dy, side1_dz, + side2_dx, side2_dy, side2_dz; + + auto dx = abs(pos_x - grid_pos_x1), + dz = abs(grid_pos_z1 - pos_z); + if (dz >= dx) + { + side1_dy = (double)(x1z1_y - x1z2_y); + side2_dy = (double)(x2z2_y - x1z2_y); + side2_dx = (double)(grid_pos_x2 - grid_pos_x1); + side1_dx = (double)(grid_pos_x1 - grid_pos_x1); + side2_dz = (double)(grid_pos_z2 - grid_pos_z2); // bug? z2 - z2 + side1_dz = (double)(grid_pos_z2 - grid_pos_z2); // z1 - z2 + Log::Warning(L"%s %s %u\n", __FILE__, __FUNCTION__, __LINE__); + /* |\ + side1 | \ + |____\ + side 2 */ + } + else + { + side1_dy = (double)(x2z2_y - x2z1_y); + side2_dy = (double)(x1z1_y - x2z1_y); + side2_dx = (double)(grid_pos_x1 - grid_pos_x2); + side1_dx = (double)(grid_pos_x2 - grid_pos_x2); + side2_dz = (double)(grid_pos_z1 - grid_pos_z1); + side1_dz = (double)(grid_pos_z2 - grid_pos_z1); + + /* side 2 + _____ + \ | + \ | side 1 + \| */ + } + + float nx = side1_dy * side2_dz - side1_dz * side2_dy; + float ny = side1_dx * side2_dy - side1_dy * side2_dx; + float nz = side1_dz * side2_dx - side1_dx * side2_dz; + + float mag = sqrt(nx * nx + ny * ny + nz * nz); + if (fabsf(mag) < 1e-6f) + { + out->y = 0; + out->x = 0; + out->z = 65536; + } + else + { + float invmag = 1.0 / mag; + out->x = invmag * nx * 65536.0; + out->y = invmag * ny * 65536.0; + out->z = invmag * nz * 65536.0; + } +} + //----- (0046DEF2) -------------------------------------------------------- unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID)