ãã®èšäºã§ã¯ãAssassin's Creed Syndicateã§åè»ã®ç©çãã·ãã¥ã¬ãŒãããããã«äœæãããç¬èªã®ã·ãã¥ã¬ãŒã¿ã«ã€ããŠã話ããããšæããŸãã ãã®ã²ãŒã ã¯ã瀟äŒã®çºå±ãèžæ°ãšééŒã«äŸåããŠããç£æ¥é©åœã®æ代ã®1868幎ã«ãã³ãã³ã§è¡ãããŸããã ãã³ãã³ã®ãã¯ããªã¢æã®äžçãå®çŸãããŠããŒã¯ãªæ©äŒã«åãçµãããšã¯ãç§ã«ãšã£ãŠå€§ããªåã³ã§ããã æŽå²çããã³å®éã®è©³çŽ°ã«æ³šæãæã£ãŠããã®ç©çã·ãã¥ã¬ãŒã·ã§ã³ãäœæããŸããã
ã¯ããã«
çŸåšãç¬èªã®ç©çãšã³ãžã³ã®äœæã¯ããŸã人æ°ããããŸããã ãã ããç¬èªã®ç©çã·ãã¥ã¬ãŒã¿ããŒãããäœæããããšãéåžžã«åœ¹ç«ã€å ŽåããããŸãã ãã®ãããªç¶æ³ã¯ãæ°ããã²ãŒã ãã¬ã€æ©èœãŸãã¯ã·ãã¥ã¬ãŒããããã²ãŒã äžçã®äžéšãç¹å¥ã«å¿ èŠãªå Žåã«çºçããå¯èœæ§ããããŸãã ããã¯ãŸãã«ã19äžçŽãã³ãã³ã®ééã·ã¹ãã ãšåè»å¶åŸ¡ã®éçºã§çããåé¡ã§ãã
ãšãŒãããã®åè»ãæ¥ç¶ããããã®æšæºã·ã¹ãã ãå³ã«ç€ºããŸãã ããš1ã€ã åãã·ã¹ãã ããã³ãã³ã®19äžçŽã®åè»ã§äœ¿çšãããŠããŸãã[1]ã åè»ã®äœæ¥ãå§ãããšããã¹ã¯ãªãŒããç©ççã«ã·ãã¥ã¬ãŒãããããšã§ãèå³æ·±ãçžäºäœçšãšäŸåé¢ä¿ãäœæã§ããããšã«ããã«æ°ä»ããŸããã ãã®ãããã¯ãŽã³ããã£ãããšåºå®ãã代ããã«ãåè»ã®ãã¹ãŠã®ã¯ãŽã³ã®åããå¶åŸ¡ããå¯åã«ãããªã³ã°è£ 眮ã§ããããæ¥ç¶ããŸããã
å³ 1.å·ŠåŽã«ã¯ããã¯ã¿ã€ã®è©³çŽ°ããããŸãïŒãœãŒã¹ïŒãŠã£ãããã£ã¢[1]ïŒã å³åŽã«ã¯ãã¢ãµã·ã³ã¯ãªãŒãã·ã³ãžã±ãŒãã®çµåã·ã¹ãã ããããŸãã
ãã®å Žåãç©çã·ãã¥ã¬ãŒã·ã§ã³ã«ã¯ããã€ãã®å©ç¹ããããŸãã
- ééç·è·¯ã®å·»ãåãã¯ã1Dã·ãã¥ã¬ãŒã¿ã䜿çšãããšç°¡åã«å¶åŸ¡ã§ããŸãã 1次å 空éã§ã¢ãŒã·ã§ã³ã³ã³ãããŒã«ãªããã¿ãŒã䜿çšããããã«3Dç©çåŠã匷å¶çã«æ¿å ¥ããããšã¯ãããªãå±éºãªæ±ºå®ã§ãã çºçããäžå®å®æ§ã«éåžžã«ææã§ããå¯èœæ§ãããããã®ããã«è»ã空äžã«é£ã³ãŸãã ãã ããå®å šãª3D空éã§ã®è»ã®è¡çªãèªèããå¿ èŠããããŸããã
- 移åå¯èœãªæ¥ç¶ã«ãããã²ãŒã ãã¬ã€èšèšã®èªç±åºŠãé«ãŸããŸãã çŸå®ã®äžçãšæ¯èŒããŠãè»ã®éã«ã¯ã¯ããã«é·ãè·é¢ãå¿ èŠã§ãã ããã¯ããã¬ãŒã€ãŒãšã«ã¡ã©ã®ããŸããŸãªã¢ã¯ã·ã§ã³ãå®è¡ããïŒããšãã°ãè»ã®å±æ ¹ã«ç»ãïŒããå€ãã®ã¹ããŒã¹ã確ä¿ããããã«å¿ èŠã§ãã ããã«ãèªåè»éã®çžå¯Ÿçãªåããããèªç±ã«ããããã«ãåœç€Ÿã®ã«ãã©ãŒã¯å®éã®äžçãããã¯ããã«å°ãªãåæ§ã§æ¥ç¶ãããŠããŸãã ããã«ãããééã®æ¥ãªæ²ããè§ã«ç°¡åã«å¯Ÿå¿ã§ããè»å士ã®è¡çªãèªèããããšã§çžäºäŸµå ¥ãé²ãããšãã§ããŸãã
- ç§ãã¡ã®ã·ã¹ãã ã®ãããã§ãã¯ãŽã³ã®é£çµè§£é€ïŒæ©æŠåãèæ ®ã«å ¥ããŠïŒããã³é£çµè§£é€ãããã¯ãŽã³ãšåè»ã®æ®ãã®éšåãšã®è¡çªã®èšç®ãå®è¡ã§ããŸãïŒããšãã°ãé£çµè§£é€ãããè»ã移åãç¶ãããã®çµæãåè»ã«è¡çªããå Žåãåè»ãçªç¶åæ¢ããå ŽåïŒã
ãããç§ãã¡ã®ç©çåŠã®ä»äºã®äŸã®ãããªã§ãïŒ
ãŸããåè»ã®å¶åŸ¡æ¹æ³ã説æããã»ã¯ã·ã§ã³ããå§ããŸãã
泚ïŒèª¬æãç°¡åã«ããããã«ãããã©ã¯ã¿ãŒããšããçšèªãæ©é¢è»ã«è¿ãã¯ãŽã³ãããã¬ãŒã©ãŒããšããçšèªãåè»ã®å°Ÿéšã«è¿ãã¯ãŽã³ãšæå®ããŸãã
æ©é¢è»å¶åŸ¡
æ©é¢è»ãå¶åŸ¡ããããã«ãå¿ èŠãªé床ã®ãªã¯ãšã¹ãã®ã¿ã§æ§æãããéåžžã«ã·ã³ãã«ãªã€ã³ã¿ãŒãã§ã€ã¹ãäœæããŸããã
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幎ã