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