アサシンクリヌドシンゞケヌトで物理を蚓緎する



この蚘事では、Assassin's Creed Syndicateで列車の物理をシミュレヌトするために䜜成された独自のシミュレヌタに぀いおお話したいず思いたす。 このゲヌムは、瀟䌚の発展が蒞気ず鉄鋌に䟝存しおいた産業革呜の時代の1868幎にロンドンで行われたした。 ロンドンのビクトリア朝の䞖界を実珟するナニヌクな機䌚に取り組むこずは、私にずっお倧きな喜びでした。 歎史的および実際の詳现に泚意を払っお、この物理シミュレヌションを䜜成したした。



はじめに



珟圚、独自の物理゚ンゞンの䜜成はあたり人気がありたせん。 ただし、独自の物理シミュレヌタをれロから䜜成するこずが非垞に圹立぀堎合がありたす。 このような状況は、新しいゲヌムプレむ機胜たたはシミュレヌトされたゲヌム䞖界の䞀郚が特別に必芁な堎合に発生する可胜性がありたす。 これはたさに、19䞖玀ロンドンの鉄道システムず列車制埡の開発で生じた問題です。



ペヌロッパの列車を接続するための暙準システムを図に瀺したす。 あず1぀。 同じシステムがロンドンの19䞖玀の列車で䜿甚されおいたした[1]。 列車の䜜業を始めたずき、スクリヌドを物理的にシミュレヌトするこずで、興味深い盞互䜜甚ず䟝存関係を䜜成できるこずにすぐに気付きたした。 そのため、ワゎンをしっかりず固定する代わりに、列車のすべおのワゎンの動きを制埡する可動カップリング装眮でそれらを接続したした。



画像

図 1.巊偎には、ネクタむの詳现がありたす゜ヌスりィキペディア[1]。 右偎には、アサシンクリヌドシンゞケヌトの結合システムがありたす。



この堎合、物理シミュレヌションにはいく぀かの利点がありたす。





これが私たちの物理孊の仕事の䟋のビデオです





たず、列車の制埡方法を説明するセクションから始めたす。



泚説明を簡単にするために、「トラクタヌ」ずいう甚語を機関車に近いワゎン、「トレヌラヌ」ずいう甚語を列車の尟郚に近いワゎンず指定したす。



機関車制埡



機関車を制埡するために、必芁な速床のリク゚ストのみで構成される非垞にシンプルなむンタヌフェむスを䜜成したした。



Locomotive::SetDesiredSpeed(float DesiredSpeed, float TimeToReachDesiredSpeed)
      
      





鉄道システム管理者は、ゲヌム内を移動する各列車にこのようなリク゚ストを送信したす。 芁求を満たすために、必芁な加速を䜜成するために必芁な力を蚈算したす。 次の匏を䜿甚したすニュヌトンの第二法則



画像



ここで、 Fは蚈算された力、 mは機関車の質量、 画像 目的の速床は珟圚の速床です、 t = TimeToReachDesiredSpeed目的の速床に達するたでの時間 。



力を蚈算した埌、それを「゚ンゞン出力」ずしおWagonPhysicsStateに転送しお、機関車を動かしたすこれに぀いおは次のセクションで詳しく説明したす。



列車の物理的挙動は、たずえば車の数に䟝存する可胜性があるため衝突する車は連鎖反応を起こし、列車を前進させたす、速床の芁求が完党に満たされるようにする方法が必芁です。 これを達成するために、2秒ごずに必芁な速床を達成するために必芁な速床を再蚈算したす。 したがっお、提出されたリク゚ストが結果ずしお満たされるこずを保蚌したす。 ただし、このため、 TimeToReachDesiredSpeedの倀ず正確に䞀臎させるこずはできたせん。 ただし、ゲヌム内でのわずかな䞀時的な逞脱は蚱容されたす。



さらに、 SetDesiredSpeedリク゚ストで指定された機関車の速床を維持するために、ゞャンクションリミッタヌで機関車の速床を倉曎するこずはできたせん。 リミッタヌからのこのようなむンパルスの欠劂を補うために、牜匕力をモデル化するための特別な方法を䜜成したした詳现に぀いおは、「列車の始動」セクションを参照しおください。 そしお最埌に、列車が速床れロたで枛速しない限り、衝突に察する反応が機関車の速床を倉えるこずを蚱可したせん。



次のセクションでは、物理シミュレヌションの基本レベルに぀いお説明したす。



基本的なシミュレヌション手順



各ワゎンおよび機関車に関する物理情報を栌玍するために䜿甚される構造は次のずおりです。



 struct WagonPhysicsState { // ,   : //     . RailwayTrack m_Track; float m_LinearMomentum; // ,   . float m_LinearSpeed; //   . float m_EngineForce; float m_FrictionForce; //     ,    . Vector m_WorldPosition; Quaternion m_WorldRotation; //   : float m_Mass; }
      
      





ご芧のずおり、角速床はありたせん。 3Dコラむダヌを䜿甚しお車同士の衝突をチェックしおもそしお、タヌンは垞に線路の方向に察応したす、列車は鉄道線路に沿っお1次元の䞖界を動きたす。 したがっお、物理孊は角運動に関する情報を保存する必芁はありたせん。 さらに、シミュレヌションは1次元であるため、物理量力、運動量、速床を保存するには、float倉数で十分です。



各車に぀いお、基本シミュレヌションのステップずしお、オむラヌ法[2]を䜿甚したす dtはシミュレヌションの1ステップの時間です。



 void WagonPhysicsState::BasicSimulationStep(float dt) { //  . float dPosition = m_LinearSpeed; float dLinearMomentum = m_EngineForce + m_FrictionForce; //  . m_LinearMomentum += dLinearMomentum*dt; m_LinearSpeed = m_LinearMomentum / m_Mass; //  . float DistanceToTravelDuringThisStep = dPosition*dt; m_Track.MoveAlongSpline( DistanceToTravelDuringThisStep ); //       . m_WorldPosition = m_Track.GetCurrentWorldPosition(); m_WorldRotation = m_Track.AlignToSpline(); }
      
      





BasicSimulationStepを実装するには、3぀の基本匏を䜿甚したす。 これらの方皋匏は、速床が䜍眮の導関数であり、力がむンパルスの導関数であるこずを瀺しおいたす蚘号の䞊の点は時間の導関数を瀺したす[2-4]。



画像



画像



3番目の方皋匏では、運動量Pが決定されたす。これは、質量ず速床の積です。



画像



私たちの実装では、車にむンパルスを適甚するこずは、珟圚のむンパルスを䜿甚した単玔な加算操䜜です。



 void WagonPhysicsState::ApplyImpulse(float AmountOfImpulse) { m_LinearMomentum += AmountOfImpulse; m_LinearSpeed = m_LinearMomentum / m_Mass; }
      
      





ご芧のずおり、勢いを倉曎した盎埌に、この倀にアクセスしやすいように速床を再蚈算したす。 これは、[2]ず同じ方法で行われたす。



これで、経時的な倉化を蚈算する基本的な方法ができたので、アルゎリズムの他の郚分に進むこずができたす。



1぀の列車に察する高レベルのシミュレヌションステップ



1぀の列車の完党なシミュレヌションステップの擬䌌コヌドは次のずおりです。



 //       //       ApplyDeferredImpulses (  ) //       UpdateCouplingChainConstraint (   ) //       UpdateEngineAndFrictionForces (    ) SimulationStepWithFindCollision (    ) CollisionResponse (  )
      
      





擬䌌コヌドで蚘述されおいるように、各パヌツは1぀の列車のすべおの貚車に察しお順番に実行されるこずに蚀及するこずが重芁です。 パヌトAは、列車の発進に関連する特別な動䜜を実装したす。 パヌトBでは、衝突䞭に埗られたむンパルスが適甚されたす。 パヌトBは、カプラヌの解法アルゎリズムであり、カプラヌの最倧距離を超えないようにしたす。 パヌトDは、゚ンゞンず摩擊の力、基本シミュレヌションのステップ統合、および衝突の凊理を担圓したす。



シミュレヌションアルゎリズムでは、電車の同じ曎新順序が垞に保持されたす。 機関車から始めお、列車のすべおの車を最初から最埌たで順番に通過したす。 このプロパティはシミュレヌタで䜿甚できるため、蚈算の定匏化が簡単になりたす。 この機胜は、衝突に接觊する堎合、各車の動きを順番にシミュレヌトする堎合、および隣接する1台の車ずの衝突を確認する堎合にのみ䜿甚したす。



この高レベルのシミュレヌションサむクルの各郚分に぀いおは、次のセクションで詳しく説明したす。 パヌトDの特別な重芁性のため、それずSimulationStepWithFindCollisionから始めたす。



衝突シミュレヌション



SimulationStepWithFindCollision関数のコヌドは次のずおりです。



 WagonPhysicsState SimulationStepWithFindCollision(WagonPhysicsState InitialState, float dt) { WagonPhysicsState NewState = InitialState; NewState.BasicSimulationStep( dt ); bool IsCollision = IsCollisionWithWagonAheadOrBehind( NewState ); if (!IsCollision) { return NewState; } return FindCollision(InitialState, dt); }
      
      





最初に、時間を完党に倉曎しおテストシミュレヌションステップを実行したす。



 NewState.BasicSimulationStep( dt );
      
      





新しい状態で衝突が怜出されたかどうかを確認したす。



 bool IsCollision = IsCollisionWithWagonAheadOrBehind( NewState );
      
      





このメ゜ッドがfalseを返す堎合、蚈算された新しい状態を盎接䜿甚できたす。 ただし、衝突が怜出された堎合は、 FindCollisionを実行しお、衝突むベントの盎前に物理孊のより正確な時間ず状態を芋぀けたす。 このタスクを達成するために、[2]で䜿甚されおいるものず同様のバむナリ怜玢を䜿甚したす。



より正確な衝突時間ず物理状態を芋぀けるためのルヌプは次のずおりです。



 WagonPhysicsState FindCollision(WagonPhysicsState CurrentPhysicsState, float TimeToSimulate) { WagonPhysicsState Result = CurrentPhysicsState; float MinTime = 0.0f; float MaxTime = TimeToSimulate; for (int step = 0 ; step<MAX_STEPS ; ++step) { float TestedTime = (MinTime + MaxTime) * 0.5f; WagonPhysicsState TestedPhysicsState = CurrentPhysicsState; TestedPhysicsState.BasicSimulationStep(TestedTime); if (IsCollisionWithWagonAheadOrBehind(TestedPhysicsState)) { MaxTime = TestedTime; } else { MinTime = TestedTime; Result = TestedPhysicsState; } } return Result; }
      
      





反埩するたびに、衝突の正確な時間に近づきたす。 たた、衝突をチェックする必芁があるのは、珟圚のキャリッゞの盎前たたは埌方に移動する堎合は埌方にあるキャリッゞ1぀のみずする必芁があるこずもわかっおいたす。 結果を蚈算するために、 IsCollisionWithWagonAheadOrBehindメ゜ッドは、2぀の指向バりンディングボックスOBB間の衝突チェックを䜿甚したす。 WagonPhysicsStateのm_WorldPositionおよびm_WorldRotationを䜿甚しお、完党な3D空間で衝突をチェックしたす。



衝突反応



衝突むベントの盎前に物理状態を受け取った埌、察応するゞェットの運動量jを蚈算しお、トラクタヌトラクタヌずトレヌラヌトレヌラヌの䞡方に適甚する必芁がありたす。 衝突前の車間の珟圚の盞察速床を蚈算するこずから始めたす。



画像



盞察速床の同様の倀 画像 衝突むベント埌



画像



どこで 画像 そしお 画像 -衝突jぞの反動のむンパルスの適甚埌の速床。 これらの速床は、衝突前の速床ず運動量jを䜿甚しお次のように蚈算できたす 画像 そしお 画像 車の塊です



画像



画像



これで、匟性回埩係数rを決定する準備ができたした。



画像



匟性回埩係数は、衝突に察する反応の「匟性」を決定したす。 r = 0の倀ぱネルギヌの完党な損倱を意味し、 r = 1の倀ぱネルギヌの損倱がないこずを意味したす絶察匟性。 この匏を前の匏に代入するず、次のようになりたす



画像



画像



運動量jを埗るためにこの方皋匏を順序付けたす



画像



画像



最埌に、運動量jを蚈算できたす。



画像



画像



ゲヌムでは、匟性回埩係数r = 0.35を䜿甚したす。



むンパルス+ jをトラクタヌに、むンパルス-jをトレヌラヌに適甚したす。 ただし、トラクタヌには「遅延」パルスを䜿甚したす。 トラクタヌの統合は既に完了しおおり、珟圚の速床を倉曎したくないため、パルスをシミュレヌションの次のフレヌムに延期したす。 芖芚的には、1぀のフレヌムの違いがほずんど芋えないため、これはあたり目立ちたせん。 このような「遅延」むンパルスは自動車甚に保存され、次のシミュレヌションフレヌムのパヌトBに適甚されたす。



列車の停留所の䟋を含むビデオ





接続スクリヌドチェヌン



接続スクリヌドを車間の距離のリミッタヌずしお䜿甚できたす。 この距離リミッタヌの芁件を満たすために、適切なパルスを蚈算しお適甚し、速床を倉曎したす。



次のシミュレヌションステップの距離方皋匏から蚈算を開始したす。 カプラヌで接続された2台の車ごずに、次のシミュレヌションステップでカバヌする距離を蚈算したす。 珟圚の速床を䜿甚しおおよび積分方皋匏を調べるこずでこの距離を非垞に簡単に蚈算できたす。



画像



ここで、 xは距離、 Vは珟圚の速床、 tはシミュレヌションのステップ時間です。



次に、匏を蚈算したす。



画像



ここで



画像 -次のシミュレヌションステップでトラクタヌがカバヌする距離。



画像 -シミュレヌションの次のステップでトレヌラヌがカバヌする距離。



FutureChainLengthがタむの最倧長よりも倧きい堎合、次のシミュレヌションステップの距離リミッタヌが壊れたす。 仮定する



画像



距離制限が壊れおいる堎合、 dの倀は正になりたす。 この堎合、距離リミッタヌの条件を満たすために、 d = 0のようなパルスを適甚する必芁がありたす。 必芁なパルスのスケヌルを確立するには、車の質量を䜿甚したす。 軜いワゎンはより倚く移動し、重いワゎンはより少なく移動する必芁がありたす。 次の係数を割り圓おたす 画像 そしお 画像



画像



画像



に泚意しおください 画像 。 シミュレヌションの次のステップで䜙分な距離を移動するトレヌラヌが必芁です 画像 距離のあるトラクタヌ 画像 。 むンパルスを適甚しおこれを達成するには、䞎えられた距離に、質量をシミュレヌションステップの時間で割った倀を掛ける必芁がありたす。



画像



画像



次の远加の係数Cを䜿甚する堎合



画像



次に、パルスの匏を単玔化しお



画像



画像



倧きさは同じですが、蚘号が異なるこずに気づくかもしれたせん。



䞡方のパルスを印加した埌、そのような接続カプラヌで接続された車は、次のシミュレヌションステップで距離制限を解陀したせん。 これらのむンパルスは、積分匏の結果ずしお、スクリヌドの最倧距離の条件を満たす䜍眮が取埗されるように速床を倉曎したす。



ただし、1぀の接続カプラヌのこれらのむンパルスを蚈算した埌でも、列車内の他の車䞡の最倧カプラヌ距離を超える可胜性がありたす。 最終的な結果を枛らすために、このメ゜ッドを数回実行する必芁がありたす。 ただし、実際には1サむクルで十分であるこずがわかりたした。 満足できる党䜓的な結果を埗るには十分です。



これらの蚈算は、機関車から始めお、列車内の接続カプラヌごずに順番に実行されたす。 カプラヌで接続された䞡方の車に垞にむンパルスを適甚したす。 ただし、このルヌルには1぀の䟋倖がありたす。機関車に勢いをかけるこずはありたせん。 速床を維持するために機関車が必芁なので、むンパルスは機関車の埌の最初の車にのみ適甚されたす。 このむンパルスはトレヌラにのみ適甚され、必芁な距離d党䜓の補償が必芁ですこの堎合、 画像 、 画像 そしお 画像 



急カヌブの修正



シミュレヌションは1次元の線に沿っお実行されるため、車が急旋回するずきにフックの接続タむが完党に䞀臎するずいう問題がありたす。 この状況では、1Dの䞖界はゲヌムの3Dの䞖界ず亀差したす。 カプラヌは3Dの䞖界にありたすが、パルス距離リミッタヌの条件を満たすための補償は、単玔化された1Dの䞖界でのみ適甚されたす。 フック䞊のカプラヌの最終䜍眮の決定を修正するために、トラクタヌずカプラヌの方向の間の盞察角床に応じおMaximumLengthOfCouplingChainをわずかに倉曎したす。 角床が倧きいほど、スクリヌドの最倧長は短くなりたす。 最初に、2぀の正芏化されたベクトルのスカラヌ積を蚈算したす。



画像



どこで 画像 -接続スクリヌドの正芏化された方向、および 画像 -トラクタヌの前方方向のベクトル。 次に、次の匏を䜿甚しお、接続スクリヌドの物理的な長さから差し匕く必芁がある距離を最終的に蚈算したす。



 float DistanceConvertedFromCosAngle = 2.0f*clamp( (1.0fs)-0.001f, 0.0f, 1.0f ); float DistanceSubtract = clamp( DistanceConvertedFromCosAngle, 0.0f, 0.9f );
      
      





ご芧のずおり、角床の正確な倀を蚈算するのではなく、コサむンを盎接䜿甚したす。 これにより、蚈算時間が少し節玄され、ニヌズに十分察応できたす。 経隓的なテストに基づいお远加の数倀を䜿甚しお、蚱容範囲内で倀を制限するこずもできたす。 最埌に、 DistanceSubtract倀を䜿甚しお、タむロッドの長さ制限の条件を満たしたす。



 MaximumLengthOfCouplingChain = ChainPhysicalLength - DistanceSubtract;
      
      





実際には、これらの匏は非垞にうたく機胜するこずが刀明したした。 これにより、トラックルヌトが急に曲がった堎合でも、タむストラップがフックに正しく掛けられたす。



次に、特別なケヌス-列車の発進に぀いお考えたす。



列車の始発



前に述べたように、接続カプラヌのむンパルスが機関車の速床を倉曎するこずは蚱可したせん。 ただし、特に電車の発進時には、トラクションの圱響をシミュレヌトする方法が必芁です。 機関車が始動するず、他の車を匕っ匵り始めたすが、車の質量に応じお機関車自䜓も枛速する必芁がありたす。 これを実珟するために、列車がれロ速床で加速するずきに速床を倉曎したす。 バランスの運動量の法則に基づいた蚈算から始めたす。 この法則は、「倖力がシステムに䜜甚しない堎合、システムの勢いは䞀定である」ず述べおいたす[3]。 これは、この堎合、勢いが 画像 別の車をけん匕する前に、それは勢いに等しくなければなりたせん 画像 接続スクリヌドが別の車を匕っ匵った盎埌



画像



画像



この堎合、これを次の匏に展開できたす。



画像



どこで 画像 -i番目のキャリッゞの質量 画像 -機関車の質量、 画像 -機関車の珟圚の速床すでに動いおいるすべおの車が機関車ず同じ速床であるず認めたす、 画像 -けん匕埌のシステムの速床すべおのけん匕車が同じ速床を持っおいるず仮定したす。 远加衚蚘を䜿甚する堎合 画像 ずしお定矩される



画像



次のように匏を単玔化できたす



画像



画像 私たちが探しおいる䟡倀は



画像



この匏を䜿甚するず、単に新しい速床を蚭定できたす 画像 機関車ず、珟圚接続カプラヌによっお匕っ匵られおいるすべおの車2〜nの堎合。

図 図2は、機関車が 画像 2台の車が3台目の車を匕っ匵り始めたす 画像 



画像

図 2.列車を開始したす。



これが列車の出発のビデオです





æ‘©æ“Š



摩擊力 WagonPhysicsStateのm_FrictionForce倉数を蚈算するには、䞀連の実隓埌に遞択され、ゲヌムプレむに最も適した匏ず倀が䜿甚されたす。 摩擊力の倀は䞀定ですが、珟圚の速床に応じおさらにスケヌリングしたす速床が4未満の堎合。 ゲヌム内の車の暙準摩擊力のグラフは次のずおりです。



画像

図 3.ワゎンの暙準摩擊力。



切断されたワゎンの堎合、他の倀が䜿甚されたす



画像

図 4.切断されたワゎンの摩擊力。



さらに、切断した埌短時間、プレむダヌがワゎンからワゎンに簡単にゞャンプできる機䌚を提䟛したいず考えたした。 そのため、より䜎い摩擊倀を䜿甚し、自動車が切断されおからの経過時間に比䟋しおスケヌリングしたした。 切断された車の摩擊の最終倀は次のように蚭定されたす。



画像



ここで、 tは、切断むベント埌の経過時間秒単䜍です。



ご芧のずおり、最初の3秒間は摩擊を䜿甚せず、埐々に増加させたす。



最新のメモ



ゲヌムトレむンでは、車の前埌に可動バンパヌを远加したした。 これらのバンパヌは、䜓力を生み出したせん。 远加の芖芚芁玠ずしおそれらの動䜜を実装したした。 それらは、別の車の隣接するバンパヌの怜出された倉䜍に埓っお移動したす。



さらに、ご芧のずおり、シミュレヌタでは異なる列車間の衝突をチェックしたせん。 鉄道システム管理者は、衝突を避けるために列車の速床を調敎する責任がありたす。 シミュレヌションでは、衝突は1぀の列車の貚車間でのみチェックされたす。



ゲヌムサりンドず特殊効果は、列車の知芚においお非垞に重芁な圹割を果たすこずを远加するこずが重芁です。 サりンドず特殊効果接続スクリヌドを匕っ匵る音、バンプ、ブレヌキなどを制埡するために、物理的な動䜜から取埗したさたざたな倀を蚈算したす。



たずめ



アサシンクリヌドシンゞケヌト甚に䜜成された物理列車シミュレヌタヌに぀いお話したした。 ゲヌムのこの郚分での䜜業は非垞に楜しく、非垞に困難でした。オヌプンワヌルドのゲヌムプレむには、倚くのゲヌムプレむ機胜ずさたざたなむンタラクションがありたす。開かれた䞖界は、安定した持続可胜なシステムを提䟛する䞊でさらに困難を生み出したす。しかし、すべおの䜜業が完了した埌、ゲヌム内で列車が移動し、ゲヌムプレむの品質に貢献するのを芋るのは非垞に楜しいです。



謝蟞



この蚘事ず圹立぀ヒントを線集しおくれたUbisoft Quebec CityのJames CarnahanずUbisoft Singaporeの䞉浊信行に感謝したす。



たた、Ubisoft Quebec Cityスタゞオの同僚であるPierre Fortinにも感謝したいず思いたす。PierreFortinは、列車物理孊の開始を支揎し、開発を促したした。テクニカルサポヌトのDave Tremblay。物理孊に関するすべおの講挔に぀いおゞェヌムズ・カヌナハン。むンスピレヌションを䞎えるアプロヌチのためのマシュヌピ゚ロ。 Maxime Begin。プログラミングに぀いおい぀も話しおくれたした。助けを求めおビンセント・マルティノヌ。さらに、マヌティン・ベダヌド、マヌク・パレントヌ、ゞョナサン・ゞェンドロン、カヌル・デュモン、パトリック・チャヌランド、゚ミル・ナデストランド、ダミアン・バヌデンに感謝したす。ダミアンバスティアン、゚リックマヌテル、スティヌブブレゞヌ、パトリックレガヌレ、アサシンクリヌドシンゞケヌトに取り組んで、このような玠晎らしいゲヌムを䜜ったギペヌム・ルピ゚ン、゚リック・ゞラヌド、そしお他のみんな



参照資料



[1]「バッファヌずチェヌンカプラヌ」、https//en.wikipedia.org/wiki/Buffers_and_chain_coupler [泚。パヌロシア語の蚘事りィキペディアにはかなり衚面的です。組成物に䜿甚される化合物の詳现に぀いおは、読むこずができるここに。]



[2]アンドリュヌ・りィットキン、デビッドBaraffによるず、マむケル・カスによっお、「入門の物理ベヌスのモデルに」、http://www.cs.cmu.edu/~baraff/pbm /



[3]フレッチャヌダン、むアンパヌベリヌ、「グラフィックスずゲヌム開発のための3D数孊入門、第2版」、CRCプレス、テむラヌフランシスグルヌプ、2011幎



。第2版​​」、モルガンカりフマン、゚ルれビア、2010幎。



All Articles