• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

修訂3d56b61a6045437bf0a2068665ce6b311d3d9a13 (tree)
時間2012-09-08 21:49:44
作者angeart <angeart@git....>
Commiterangeart

Log Message

ver0.2.3 ジャンプ式の最終確定(恐らく)

Change Summary

差異

--- a/client/3d/PlayerCharacter.cpp
+++ b/client/3d/PlayerCharacter.cpp
@@ -8,6 +8,18 @@
88 #include "MotionPlayer.hpp"
99 #include "../../common/Logger.hpp"
1010
11+
12+namespace
13+{
14+
15+template <typename T, typename U>
16+inline bool NearlyEqualRelative(const T& lhs, const T& rhs, const U& ratio)
17+{
18+ return abs(lhs - rhs) <= ratio * abs(rhs);
19+}
20+
21+}
22+
1123 class PlayerCharacter::Impl
1224 {
1325 public:
@@ -16,8 +28,14 @@ public:
1628 model_handle_(-1),
1729 current_target_pos_(VGet(0, 1000, 0)),
1830 prev_target_pos_(VGet(0, 1000, 0)),
31+ current_target_vec_y_(0.0f),
1932 current_rot_(VGet(0, 0, 0)),
2033 prev_rot_(VGet(0, 0, 0)),
34+ move_vec_y_(0.0f),
35+ jump_flag_(false),
36+ flight_duration_ideal_(1.0f),
37+ model_height_(1.58f),
38+ jump_height_(sqrt(15.0f)*2.0f),
2139 current_motion_(-1),
2240 prev_motion_(-1),
2341 current_speed_(0),
@@ -32,7 +50,10 @@ public:
3250 motion.walk_ = MV1GetAnimIndex(model_handle_, _T("walk"));
3351 motion.run_ = MV1GetAnimIndex(model_handle_, _T("run"));
3452 motion_player_.reset(new MotionPlayer(model_handle_));
35- }
53+
54+ model_height_ = data_provider_.model().property().get<float>("character.height",1.58f);
55+ flight_duration_ideal_ = sqrt((model_height_*2.0f)/9.8f) + sqrt((model_height_*0.8f)/9.8);
56+ }
3657
3758 void Impl::Draw() const
3859 {
@@ -43,8 +64,16 @@ public:
4364
4465 void Impl::Update()
4566 {
67+ static auto time_now = 0.0f;
68+ prev_target_pos_ = current_target_pos_;
4669 const auto current_target_pos = data_provider_.target_position();
70+ const auto current_target_vec_y_ = data_provider_.vy();
4771 // if (current_target_pos.y == 0) return;
72+ if(current_target_pos != prev_target_pos_ )
73+ {
74+ time_now = 0.0f;
75+ }
76+
4877
4978 current_target_pos_ = current_target_pos;
5079 current_pos_ = MV1GetPosition(model_handle_);
@@ -73,50 +102,150 @@ public:
73102
74103 //Logger::Debug("distance_to_target: %d %d", distance_to_target, current_speed_ * timer_->DeltaSec());
75104
76- if (current_speed_ * timer_->DeltaSec() > 0.2)
77- {
78- current_motion_ = motion.run_;
79- }
80- else
81- {
82- current_motion_ = motion.stand_;
83- }
84-
85- if (current_motion_ != prev_motion_ && current_motion_ != -1)
86- {
87- motion_player_->Play(current_motion_, false, 200, -1, false);
88- prev_motion_ = current_motion_;
89- }else if(additional_motion_.first)
90- {
91- bool connect_prev = true;
92- motion_player_->Play(additional_motion_.second, connect_prev, 200, -1, false);
93- additional_motion_.first = false;
94- }
95-
96105 // TODO: Y下方向については重力加速度
97106 if (distance_to_target > 2.0){
98- const auto direction = current_target_pos_ - current_pos_;
107+ auto direction = current_target_pos_ - current_pos_;
99108 const auto diff_pos = VAdjustLength(direction, current_speed_ * timer_->DeltaSec());
100109 const float roty = atan2(-direction.x, -direction.z);
110+ const auto time_entire = VSize(direction) / (current_speed_ * (float)timer_->DeltaSec()); // ターゲットまでの移動完了時間
111+ time_now += timer_->DeltaSec(); // タイマーのカウントアップ
101112
102113 current_rot_ = VGet(0, roty, 0);
103114 //std::cout << "set pos to " << MV1GetPosition(model_handle_) + diff_pos << std::endl;
104115
116+ /*
117+ const auto jump_result_y =
118+ jump_height_ * stage_->map_scale() * (time_entire - time_now) * (jump_height_ / 5.0f) * 1.019952f +
119+ 0.5f * -9.8f * (time_entire - time_now) * (time_entire - time_now) * (1.0f / flight_duration_ideal_) * (jump_height_ / 5.0f) * (jump_height_ / 5.0f); // 今からジャンプした際の最終的な位置
120+ */
121+ static auto st_acc = -9.8f;
122+ auto acc = -6.5f;
123+ auto prediction_vector = 0.0f;
124+
125+ for(acc;acc < -11.0f;acc-=0.1f){
126+ prediction_vector = jump_height_ * stage_->map_scale() + (acc) * (time_entire - time_now) * (jump_height_ / 5.0f) * (1.0f / flight_duration_ideal_ );
127+ if( current_target_vec_y_ != 0 && jump_flag_ == false )
128+ {
129+ // ターゲット座標ではジャンプを始めている
130+ if( prediction_vector > current_target_vec_y_ - 1 && prediction_vector < current_target_vec_y_ + 1)
131+ {
132+ // 目標座標でベクトルが上向きなら一致、ジャンプを始める
133+ move_vec_y_ = jump_height_ * stage_->map_scale();
134+ jump_flag_ = true;
135+ }// それ以外はそのまま
136+ }
137+ }
138+ st_acc = acc;
139+
140+ VECTOR moved_pos;
141+ moved_pos = current_pos_ + diff_pos;
142+ if( jump_flag_ == true )
143+ {
144+ move_vec_y_ += (st_acc * stage_->map_scale() * timer_->DeltaSec() * (1.0f/flight_duration_ideal_) * (jump_height_ / 5.0f));
145+ moved_pos.y = current_pos_.y + move_vec_y_ * timer_->DeltaSec() * (jump_height_ / 5.0f);
146+ }
147+ Logger::Debug(_T("move_vec_y %.3f"), move_vec_y_);
148+
105149 // 床へのめり込みを防止
106- VECTOR moved_pos = current_pos_ + diff_pos;
107150 float floor_y;
108- for (int i = 1;
109- i < 10 && !(stage_->GetFloorY(moved_pos + VGet(0,10 * i,0), moved_pos + VGet(0,-10 * i,0), &floor_y));
110- i+=2);
111- moved_pos.y = std::max(moved_pos.y, floor_y);
151+ std::pair<bool, VECTOR> floor_coll;
152+ if(jump_flag_ == false)
153+ {
154+ // 延長線上で接地検査
155+ floor_coll = stage_->FloorExists(moved_pos,model_height_,8.0f);
156+ }else if(jump_flag_ == true && current_pos_.y >= moved_pos.y)
157+ {
158+ // 足で接地検査
159+ floor_coll = stage_->FloorExists(moved_pos,model_height_,0);
160+ }
161+ //moved_pos.y = std::max(moved_pos.y, floor_y); // 床にあたっているときは床の方がyが高くなる
162+ if(jump_flag_ == false){
163+ // 登ったり下ったりできる段差の大きさの制限を求める
164+ static const float y_max_limit_factor = sin(45 * PHI_F / 180);
165+ static const float y_min_limit_factor = sin(-45 * PHI_F / 180);
166+ const float y_max_limit = y_max_limit_factor * VSize(diff_pos);
167+ const float y_min_limit = y_min_limit_factor * VSize(diff_pos);
168+
169+ // 接地点計算
170+ //std::cout << " ground collision check: current pos = " << current_stat_.pos << std::endl;
171+
172+ auto coll_info = MV1CollCheck_Line(stage_->map_handle().handle(), -1,
173+ moved_pos + VGet(0, y_max_limit, 0),
174+ moved_pos + VGet(0, y_min_limit, 0));
175+ if(coll_info.HitFlag && NearlyEqualRelative(coll_info.HitPosition.y, floor_coll.second.y, 0.001)){
176+ // 接地可能
177+ auto diff = coll_info.HitPosition - current_pos_;
178+
179+ // 角度が急になるほどdiffの長さが大きくなるから、補正する
180+ if (VSize(diff) > 0)
181+ {
182+ moved_pos = current_pos_ + VSize(diff_pos) * VNorm(diff);
183+ }
184+
185+ }
186+ if( floor_coll.first )
187+ {
188+ if( floor_coll.second.y < moved_pos.y )
189+ {
190+ jump_flag_ = true;
191+ }
192+ }
193+ //move_vec_y_ = 0;
194+ }else{
195+ if( moved_pos.y <= current_pos_.y )
196+ {
197+ if( floor_coll.first )
198+ {
199+ moved_pos = floor_coll.second;
200+ move_vec_y_ = 0;
201+ }
202+ }else{
203+ // 上昇している
204+
205+ const auto player_top = VGet(0, model_height_ * stage_->map_scale(), 0);
206+ auto coll_info = MV1CollCheck_Line(stage_->map_handle().handle(), -1,
207+ current_pos_ + player_top,
208+ moved_pos + player_top);
209+ if (coll_info.HitFlag)
210+ {
211+ // 天井に到達した
212+ // std::cout << " current collided to ceiling" << std::endl;
213+
214+ moved_pos = coll_info.HitPosition - player_top;
215+ move_vec_y_ = -(move_vec_y_ - (st_acc * stage_->map_scale() * timer_->DeltaSec() * (1.0f/flight_duration_ideal_) * (jump_height_ / 5.0f))) * 1.0; // 反射
216+ }
217+ }
218+ }
112219
113220 data_provider_.set_position(moved_pos);
114221 data_provider_.set_theta(current_rot_.y);
115222
116223 MV1SetPosition(model_handle_, moved_pos);
117- MV1SetRotationXYZ(model_handle_, current_rot_);
224+ MV1SetRotationXYZ(model_handle_, current_rot_);
225+
226+ if (current_speed_ * timer_->DeltaSec() > 0.205f)
227+ {
228+ current_motion_ = motion.run_;
229+ }
230+ else
231+ {
232+ current_motion_ = motion.walk_;
233+ }
234+ }else{
235+ current_motion_ = motion.stand_;
118236 }
119237
238+ if (current_motion_ != prev_motion_ && current_motion_ != -1)
239+ {
240+ motion_player_->Play(current_motion_, false, 200, -1, false);
241+ prev_motion_ = current_motion_;
242+ }else if(additional_motion_.first)
243+ {
244+ bool connect_prev = true;
245+ motion_player_->Play(additional_motion_.second, connect_prev, 200, -1, false);
246+ additional_motion_.first = false;
247+ }
248+
120249 } else {
121250 // 離れすぎている場合は瞬間移動
122251
@@ -138,9 +267,15 @@ private:
138267 CharacterDataProvider& data_provider_;
139268 int model_handle_;
140269 VECTOR current_target_pos_;
141- VECTOR prev_target_pos_;
270+ VECTOR prev_target_pos_; // ひとつ前のターゲット
142271 VECTOR current_pos_;
143272 VECTOR current_rot_, prev_rot_;
273+ float current_target_vec_y_;
274+ float move_vec_y_;
275+ bool jump_flag_;
276+ float flight_duration_ideal_;
277+ float model_height_;
278+ float jump_height_;
144279 int current_motion_;
145280 int prev_motion_;
146281 float current_speed_;
--- a/client/version.hpp
+++ b/client/version.hpp
@@ -9,7 +9,7 @@
99
1010 #define MMO_VERSION_MAJOR 0
1111 #define MMO_VERSION_MINOR 2
12-#define MMO_VERSION_REVISION 2
12+#define MMO_VERSION_REVISION 3
1313
1414 #ifdef MMO_VERSION_BUILD
1515 #define MMO_VERSION_BUILD_TEXT " Build " MMO_VERSION_TOSTRING(MMO_VERSION_BUILD)