| 1213 | |
| 1214 | static const float fmove_steps_max_num = move_steps_max_num; |
| 1215 | void CPHMovementControl::VirtualMoveTo(const Fvector& in_pos, Fvector& out_pos) |
| 1216 | { |
| 1217 | VERIFY(CharacterExist()); |
| 1218 | VERIFY(_valid(in_pos)); |
| 1219 | |
| 1220 | class ph_character_state_save |
| 1221 | { |
| 1222 | public: |
| 1223 | ph_character_state_save(CPHCharacter* character) : character_(character), saved_callback_(character->ObjectContactCallBack()) |
| 1224 | { |
| 1225 | character_->get_State(sv_state); |
| 1226 | /////////////////////////////////////// |
| 1227 | character_->SetObjectContactCallback(virtual_move_collide_callback); |
| 1228 | character_->SetObjectContactCallbackData(static_cast<CPHObject*>(character)); |
| 1229 | character_->SwitchOFFInitContact(); |
| 1230 | character_->SetApplyGravity(FALSE); |
| 1231 | } |
| 1232 | |
| 1233 | ~ph_character_state_save() |
| 1234 | { |
| 1235 | character_->SetObjectContactCallback(saved_callback_); |
| 1236 | character_->SwitchInInitContact(); |
| 1237 | character_->SetApplyGravity(TRUE); |
| 1238 | character_->SetObjectContactCallbackData(nullptr); |
| 1239 | character_->set_State(sv_state); |
| 1240 | } |
| 1241 | |
| 1242 | private: |
| 1243 | SPHNetState sv_state; |
| 1244 | CPHCharacter* character_; |
| 1245 | ObjectContactCallbackFun* saved_callback_; |
| 1246 | |
| 1247 | } cleanup(m_character); |
| 1248 | |
| 1249 | const Fvector displacement = Fvector().sub(in_pos, vPosition); |
| 1250 | const float dist = displacement.magnitude(); |
| 1251 | if (fis_zero(dist)) |
| 1252 | { |
| 1253 | out_pos.set(in_pos); |
| 1254 | return; |
| 1255 | } |
| 1256 | |
| 1257 | float move_time = dist / move_velocity; |
| 1258 | float n = move_time / fixed_step; |
| 1259 | float fsteps_num = ceil(n); |
| 1260 | u32 steps_num = iCeil(n); |
| 1261 | clamp(fsteps_num, 0.f, fmove_steps_max_num); |
| 1262 | clamp<u32>(steps_num, u32(0), move_steps_max_num); |
| 1263 | |
| 1264 | move_time = fixed_step * fsteps_num; |
| 1265 | const float calc_velocity = dist / move_time; |
| 1266 | const float force = calc_velocity * m_character->Mass() / fixed_step; |
| 1267 | const Fvector vforce = Fvector().mul(displacement, force / dist); |
| 1268 | |
| 1269 | m_character->Enable(); |
| 1270 | |
| 1271 | for (u32 i = 0; i < steps_num; ++i) |
| 1272 | { |
no test coverage detected