Mercurial > mm7
comparison 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 |
comparison
equal
deleted
inserted
replaced
137:a2ddaf0e4d8a | 138:a8ec7e1e18b6 |
---|---|
975 LABEL_54: | 975 LABEL_54: |
976 *(int *)a4 = 0; | 976 *(int *)a4 = 0; |
977 return dword_720F20[v22]; | 977 return dword_720F20[v22]; |
978 } | 978 } |
979 | 979 |
980 | |
981 //not sure if right- or left-handed coordinate space assumed, so this could be normal of inverse normal | |
982 // for a right-handed system, that would be an inverse normal | |
980 //----- (0046DCC8) -------------------------------------------------------- | 983 //----- (0046DCC8) -------------------------------------------------------- |
981 signed __int64 __fastcall _46DCC8_get_gravity_direction_outdoor(int a1, int a2, Vec3_int_ *a3) | 984 void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out) |
982 { | 985 { |
983 int v3; // ebx@1 | 986 auto grid_x = WorldPosToGridCellX(pos_x); |
984 int v4; // ST4C_4@1 | 987 auto grid_z = WorldPosToGridCellZ(pos_z) - 1; |
985 unsigned int v5; // ST54_4@1 | 988 |
986 unsigned int v6; // edi@1 | 989 auto grid_pos_x1 = GridCellToWorldPosX(grid_x); |
987 unsigned int v7; // ST50_4@1 | 990 auto grid_pos_x2 = GridCellToWorldPosX(grid_x + 1); |
988 int v8; // edi@1 | 991 auto grid_pos_z1 = GridCellToWorldPosZ(grid_z); |
989 int v9; // esi@1 | 992 auto grid_pos_z2 = GridCellToWorldPosZ(grid_z + 1); |
990 int v10; // ebx@1 | 993 |
991 int v11; // ecx@2 | 994 auto x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z); |
992 int v12; // eax@2 | 995 auto x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z); |
993 int v13; // edx@2 | 996 auto x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1); |
994 int v14; // ebx@2 | 997 auto x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); |
995 double v15; // st7@4 | 998 |
996 double v16; // st6@4 | 999 float side1_dx, side1_dy, side1_dz, |
997 double v17; // st5@4 | 1000 side2_dx, side2_dy, side2_dz; |
998 float v18; // ST44_4@4 | 1001 |
999 float v19; // ST54_4@4 | 1002 auto dx = abs(pos_x - grid_pos_x1), |
1000 double v20; // st4@4 | 1003 dz = abs(grid_pos_z1 - pos_z); |
1001 double v21; // st5@4 | 1004 if (dz >= dx) |
1002 float v22; // ST44_4@6 | 1005 { |
1003 double v23; // st7@4 | 1006 side1_dy = (double)(x1z1_y - x1z2_y); |
1004 double v24; // st7@6 | 1007 side2_dy = (double)(x2z2_y - x1z2_y); |
1005 signed __int64 result; // qax@6 | 1008 side2_dx = (double)(grid_pos_x2 - grid_pos_x1); |
1006 int v26; // [sp+14h] [bp-44h]@1 | 1009 side1_dx = (double)(grid_pos_x1 - grid_pos_x1); |
1007 int v27; // [sp+18h] [bp-40h]@1 | 1010 side2_dz = (double)(grid_pos_z2 - grid_pos_z2); // bug? z2 - z2 |
1008 int v28; // [sp+20h] [bp-38h]@1 | 1011 side1_dz = (double)(grid_pos_z2 - grid_pos_z2); // z1 - z2 |
1009 int v29; // [sp+24h] [bp-34h]@1 | 1012 Log::Warning(L"%s %s %u\n", __FILE__, __FUNCTION__, __LINE__); |
1010 int v30; // [sp+28h] [bp-30h]@1 | 1013 /* |\ |
1011 int v31; // [sp+2Ch] [bp-2Ch]@1 | 1014 side1 | \ |
1012 int v32; // [sp+30h] [bp-28h]@1 | 1015 |____\ |
1013 int v33; // [sp+34h] [bp-24h]@1 | 1016 side 2 */ |
1014 int v34; // [sp+38h] [bp-20h]@1 | |
1015 int v35; // [sp+3Ch] [bp-1Ch]@1 | |
1016 int v36; // [sp+40h] [bp-18h]@1 | |
1017 int v37; // [sp+4Ch] [bp-Ch]@2 | |
1018 float v38; // [sp+4Ch] [bp-Ch]@4 | |
1019 int v39; // [sp+50h] [bp-8h]@2 | |
1020 float v40; // [sp+50h] [bp-8h]@4 | |
1021 int v41; // [sp+54h] [bp-4h]@2 | |
1022 | |
1023 v3 = a1; | |
1024 v4 = a2; | |
1025 v5 = WorldPosToGridCellX(a1); | |
1026 v6 = WorldPosToGridCellZ(v4) - 1; | |
1027 v33 = GridCellToWorldPosX(v5); | |
1028 v34 = GridCellToWorldPosX(v5 + 1); | |
1029 v35 = GridCellToWorldPosX(v5 + 1); | |
1030 v36 = GridCellToWorldPosX(v5); | |
1031 v29 = GridCellToWorldPosZ(v6); | |
1032 v30 = GridCellToWorldPosZ(v6); | |
1033 v7 = v6 + 1; | |
1034 v31 = GridCellToWorldPosZ(v6 + 1); | |
1035 v32 = GridCellToWorldPosZ(v6 + 1); | |
1036 v26 = pOutdoor->DoGetHeightOnTerrain(v5, v6); | |
1037 v27 = pOutdoor->DoGetHeightOnTerrain(v5 + 1, v6); | |
1038 v8 = pOutdoor->DoGetHeightOnTerrain(v5 + 1, v6 + 1); | |
1039 v28 = pOutdoor->DoGetHeightOnTerrain(v5, v7); | |
1040 v9 = v29; | |
1041 v10 = abs(v3 - v33); | |
1042 if ( abs(v29 - v4) >= v10 ) | |
1043 { | |
1044 v11 = v33; | |
1045 v37 = v28; | |
1046 v39 = v36; | |
1047 v12 = v35; | |
1048 v41 = v32; | |
1049 v13 = v31; | |
1050 v14 = v8; | |
1051 v8 = v26; | |
1052 } | 1017 } |
1053 else | 1018 else |
1054 { | 1019 { |
1055 v11 = v35; | 1020 side1_dy = (double)(x2z2_y - x2z1_y); |
1056 v41 = v30; | 1021 side2_dy = (double)(x1z1_y - x2z1_y); |
1057 v39 = v34; | 1022 side2_dx = (double)(grid_pos_x1 - grid_pos_x2); |
1058 v12 = v33; | 1023 side1_dx = (double)(grid_pos_x2 - grid_pos_x2); |
1059 v13 = v29; | 1024 side2_dz = (double)(grid_pos_z1 - grid_pos_z1); |
1060 v9 = v31; | 1025 side1_dz = (double)(grid_pos_z2 - grid_pos_z1); |
1061 v37 = v27; | 1026 |
1062 v14 = v26; | 1027 /* side 2 |
1063 } | 1028 _____ |
1064 v15 = (double)(v12 - v39); | 1029 \ | |
1065 v16 = (double)(v13 - v41); | 1030 \ | side 1 |
1066 v17 = (double)(v14 - v37); | 1031 \| */ |
1067 v18 = (double)(v11 - v39); | 1032 } |
1068 v19 = (double)(v9 - v41); | 1033 |
1069 v20 = (double)(v8 - v37); | 1034 float nx = side1_dy * side2_dz - side1_dz * side2_dy; |
1070 v38 = v20 * v16 - v19 * v17; | 1035 float ny = side1_dx * side2_dy - side1_dy * side2_dx; |
1071 v40 = v18 * v17 - v20 * v15; | 1036 float nz = side1_dz * side2_dx - side1_dx * side2_dz; |
1072 v21 = v19 * v15 - v18 * v16; | 1037 |
1073 v23 = sqrt(v21 * v21 + v40 * v40 + v38 * v38); | 1038 float mag = sqrt(nx * nx + ny * ny + nz * nz); |
1074 if ( v23 == 0.0 ) | 1039 if (fabsf(mag) < 1e-6f) |
1075 { | 1040 { |
1076 a3->y = 0; | 1041 out->y = 0; |
1077 a3->x = 0; | 1042 out->x = 0; |
1078 a3->z = 65536; | 1043 out->z = 65536; |
1079 } | 1044 } |
1080 v24 = 1.0 / v23; | 1045 else |
1081 a3->x = (signed __int64)(v24 * v38 * 65536.0); | 1046 { |
1082 a3->y = (signed __int64)(v24 * v40 * 65536.0); | 1047 float invmag = 1.0 / mag; |
1083 v22 = v21; | 1048 out->x = invmag * nx * 65536.0; |
1084 result = (signed __int64)(v24 * v22 * 65536.0); | 1049 out->y = invmag * ny * 65536.0; |
1085 a3->z = result; | 1050 out->z = invmag * nz * 65536.0; |
1086 return result; | 1051 } |
1087 } | 1052 } |
1088 // 47F44B: using guessed type int __stdcall WorldPosToGridCellX(int); | 1053 |
1089 // 47F458: using guessed type int __stdcall WorldPosToGridCellZ(int); | |
1090 // 47F469: using guessed type int __stdcall GridCellToWorldPosX(int); | |
1091 // 47F476: using guessed type int __stdcall GridCellToWorldPosZ(int); | |
1092 | 1054 |
1093 //----- (0046DEF2) -------------------------------------------------------- | 1055 //----- (0046DEF2) -------------------------------------------------------- |
1094 unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID) | 1056 unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID) |
1095 { | 1057 { |
1096 unsigned int result; // eax@1 | 1058 unsigned int result; // eax@1 |