約 1,962,299 件
https://w.atwiki.jp/taziro/pages/50.html
[目次] <前ページ> 衝突検出 広域な衝突検出 厳密な衝突検出 AABB グリッド コリジョングループとカテゴリー コリジョンイベント 衝撃力 物理プロパティ Farseer の拡張 テクスチャからの頂点作成 パスジェネレーター パフォーマンス 既知の問題 [衝突検出] Farseer Physics Engine は使いやすい4つの異なる区分を含むコリジョンシステムを提供します: 1. 広域な衝突検出 2. 厳密な衝突検出 3. AABB (Axis Aligned Bounding Box) 4. グリッドの衝突検出 それぞれのシステムについて、以下に説明します: [広域な衝突検出] 広域な衝突検出は、エンジンがしなければならない仕事を減らして衝突検出の速度を上げるために、先進のアルゴリズムに頼ります。現在、3種類の広域な衝突検出アルゴリズムがあります: 1. Sweep And Prune (SAP と呼ばれます) 2. Selective Sweep 3. Brute Force Sweep And Prune アルゴリズムはフレームコヒーレントです。これは画面外に多くのオブジェクトがある場合には、悪い選択となるかもしれないということを意味しますまた、これはオブジェクトが近い位置にあるのなら、最後のフレームにあり、このアルゴリズムは良いことを意味します。SAP アルゴリズムではオブジェクトがテレポートする、またはすごい速さでワールドの端から端まで移動する、または弾丸が好ましくないことに注意して下さい。それにより壊れてしまい、信頼できない衝突を引き起こすかもしれません。SAP の詳細情報はこことここで見ることができます。 Selective Sweep アルゴリズムは BioSlayer 氏によって開発されました。Farseer Physics Engine のデフォルトは SS アルゴリズムです。SS は当初、 Sweep And Prune の上に構築されましたが、SAP よりもパフォーマンスを向上させるためにいくつかの変更がなされました。More information on SS can be found here. SS の詳細情報はここで見ることができます。 Brute Force アルゴリズムはこれらの中で最もシンプルです。しかし3つの中で最も実行速度が遅いですワールド上の全てのジオメトリを辿り、その AABB を比較します。Brute Force アルゴリズムの計算量は O(n^2) です。しかしジオメトリの数が少なければとても速いです。 [厳密な衝突検出] 厳密な衝突検出は、広域な衝突検出で衝突した全てのペアで発生し、さらにそれらの計算を行います。全ての厳密な衝突検出のコードは、Arbiter クラスの中にあります。下記に厳密な衝突検出で行われることの概要を記載します。広域な衝突検出によって、アービターオブジェクトの中に衝突しているジオメトリのペアが検出されていると仮定します。 1) 最初のジオメトリが持つ全てのワールド座標上の頂点を辿ります。 2) 現在のベクトルが2番目のジオメトリと交差するか? a) false (交差しない): 頂点リストの次のベクトルを計算します。 b) true (交差する): 接触情報を作成し、接触情報リストに挿入します。 3) 1) と 2) を2番目のジオメトリで行います。 4) 接触情報リストに何らかの接触情報があれば、OnCollision イベントに2つのジオメトリと接触情報リストを渡し、呼び出して下さい。 Arbiter クラスは、衝突するときにジオメトリに適用される衝撃力を計算するのにも使用されます。 [AABB] AABB は Axis Aligned Bounding Box の略で、名前が示す通り、軸に平行なバウンディングボックスです。全てのジオメトリはそれぞれの更新時に再計算される AABB を持っています。AABB は比較的安価で2つのジオメトリがお互いに近くにある (もしくは接触している) かどうかを高速にテストするのに使用されます。 下記のようにすると、2つのジオメトリがお互いに近くにあるかどうかをテストできます: if (AABB.Intersect(_circleGeom.AABB,_rectangleGeom.AABB)){ //The 2 AABB s intersect} AABB は回転せず、またアウトラインはジオメトリの長方形ですので、2つの AABB の交差判定を行ったとき、実際には接触していないかもしれないということを覚えておいて下さい。 下の図を見てください。 交差 交差と衝突 (接触) AABB は黒いジオメトリのアウトラインです。見ての通り、それらは回転しておらず、また軸に平行です。本当に接触していれば、衝突するときに生成された赤い接触点が表示されます。 [グリッド] 全てのジオメトリはグリッドオブジェクトを含んでいます。厳密な衝突判定で使用されており、そして距離グリッドを使用します。距離グリッドは、グリッドのそれぞれの点のジオメトリ上で最も近い点とその点の法線を事前計算しています。(法線についての詳細は「物理」の章に記載しています) ジオメトリの内側にある全てのグリッド点の距離は負の数になります。下にグリッドとその点の図を示します: 距離グリッドは一度、事前計算されると、どんなグリッドの中間点の距離と法線も、分かっている点の値で補完することで計算できます。Geom のコンストラクタ、または GeomFactory を使用したとき、グリッドは指定されたグリッドのセルサイズから計算されますグリッドのセルサイズが小さければ、グリッドがより正確なり、またそれによって衝突検出が正確になります。 グリッドの計算はかなり時間がかかることがありますので、事前にすべてのジオメトリの具体例を示して、ちょうど良いグリッドのセルサイズを選ぶという方法は、良いアイデアかもしれません。この詳細については「パフォーマンス」の章に記載しています。 [コリジョングループとカテゴリー] Farseer は、異なるコリジョングループとさらに先進的なコリジョンカテゴリーを構築する方法を提供します。 デフォルトで、全てのジオメトリはコリジョングループ 0 にあり、これは他の全てのジオメトリと衝突することを意味します。2つのジオメトリが同じコリジョングループにある場合は、お互いに衝突しませんが、コリジョングループ 0 は例外です。 下記にをどのようにジオメトリのコリジョングループを設定するかを示します: Body rectBody = BodyFactory.Instance.CreateRectangleBody(PhysicsSimulator, 128, 128, 1); rectBody.Position = new Vector2(250, 400); Geom rectGeom = GeomFactory.Instance.CreateRectangleGeom(PhysicsSimulator, rectBody, 128, 128); rectGeom.CollisionGroup = 10; Body circleBody = BodyFactory.Instance.CreateCircleBody(PhysicsSimulator, 64, 1); circleBody.Position = new Vector2(300, 400); Geom circleGeom = GeomFactory.Instance.CreateCircleGeom(PhysicsSimulator, circleBody, 64, 20); circleGeom.CollisionGroup = 10; もし rectGeom と circleGeom が重なり合っているとしても、お互いに衝突しません。コリジョングループは使いやすいですが、できる事が非常に制限されます。それがコリジョンカテゴリーも存在している理由です。 コリジョンカテゴリーを使用するときに興味深い2つのプロパティがあります: 1) CollisionCategories a) デフォルトは CollisionCategory.All です。 b) ジオメトリがどこのメンバーなのかを定義するために使用されます。 2) CollidesWith a) デフォルトは CollisionCategory.All です。 b) ジオメトリがどこのメンバーと衝突するのかを定義するために使用されます。 コリジョンカテゴリーは CollisionCategory と呼ばれる列挙型を使い、その特別なフラグを有効にします。これはビット演算子で行うことができます。(詳細はここを見て下さい) 例: Body rectBody = BodyFactory.Instance.CreateRectangleBody(PhysicsSimulator, 128, 128, 1);rectBody.Position = new Vector2(250, 400);Geom rectGeom = GeomFactory.Instance.CreateRectangleGeom(PhysicsSimulator, rectBody, 128, 128);rectGeom.CollisionCategory = CollisionCategories.Cat5; rectGeom.CollidesWith = CollisionCategories.All ~CollisionCategories.Cat4; Body circleBody = BodyFactory.Instance.CreateCircleBody(PhysicsSimulator, 64, 1); circleBody.Position = new Vector2(300, 400); Geom circleGeom = GeomFactory.Instance.CreateCircleGeom(PhysicsSimulator, circleBody, 64, 20); circleGeom.CollisionCategory = CollisionCategories.Cat4; circleGeom.CollidesWith = CollisionCategories.All ~CollisionCategories.Cat5; 今回、rectGeom は Cat5 (Category 5) のメンバーで、Cat4 以外の全てと衝突します。 circleGeom Cat4 のメンバーで、Cat5 以外の全てと衝突します。 これは2つのジオメトリがお互いに衝突しないことを意味します。 [コリジョンイベント] 3つの異なったコリジョンイベントがあります。 1. OnCollision (in Geom class) 2. OnSeparation (in Geom class) 3. OnBroadPhaseCollision (in IBroadPhaseCollider interface) OnCollision イベントはジオメトリが他のジオメトリと衝突したときに呼び出されます。イベントメソッドは衝突によって何かが起こったのかどうかを boolean で返す必要があります。 OnSeparation イベントはジオメトリが他のジオメトリと切り離された後に呼び出されます。 OnBroadPhaseCollision イベントは OnCollision イベントと似ていますが、広域な衝突検出のときにもうすでに呼び出されます。 このイベントをキャンセルするとアービターが作成されません。これは衝撃力が適用されず、また関係しているジオメトリの厳密な衝突検出も行われないことを意味します。 イベントの登録方法を下記に記します: Body circleBody = BodyFactory.Instance.CreateCircleBody(PhysicsSimulator, 64, 1); Geom circleGeom = GeomFactory.Instance.CreateCircleGeom(PhysicsSimulator, circleBody, 64, 20); circleGeom.OnSeparation += OnSeperation; circleGeom.OnCollision += OnCollision; PhysicsSimulator.BroadPhaseCollider.OnBroadPhaseCollision += OnBroadPhaseCollision; OnBroadPhaseCollision イベントは PhysicsSimulator の BroadPhaseCollider に登録されることに注意して下さい。 そして、イベントが発生したときにメソッドが実行されます: private bool OnCollision(Geom geom1, Geom geom2, ContactList contactList) { return true; } private void OnSeperation(Geom geom1, Geom geom2) { } private bool OnBroadPhaseCollision(Geom geom1, Geom geom2) { return true;} [衝撃力] 2つの衝撃力システムがあります。 1. 衝突の反応 2. 手動の衝撃力 衝突の反応は、2つのジオメトリがお互いに衝突したときに発生します。 「厳密な衝突検出」の章に記載されている Arbiter クラスは、衝突が発生したときに衝撃力の計算に対して責任を持ちます。もう少し技術的に考えると、接触点が厳密な衝突判定で計算され、衝撃力が適用されることにより、ジオメトリは実際の物理のように振る舞います。 衝突の反応は、下記のように ジオメトリの CollisionResponseEnabled に false を設定することで無効にすることができます: Geom circleGeom = GeomFactory.Instance.CreateCircleGeom(PhysicsSimulator, circleBody, 64, 20); circleGeom.CollisionResponseEnabled = false; 衝突の反応を無効にするということは、全てのジオメトリをすり抜けることを意味します。「コリジョンイベント」の章に記載しているコリジョンイベントは発生します。 また、手動でボディに衝撃力を適用することもできます。(ボディはダイナミクスをコントロールし、ジオメトリは衝突をコントロールしますが、アービターは衝突に関するジオメトリの衝撃力をコントロールすることを覚えておいて下さい。) ボディにフォース/衝撃力を適用する方法が3つあります。 以下にフォースとそのメソッドのリストを示します: 1. フォース 1. ApplyForce 2. ApplyForceAtLocalPoint 3. ApplyForceAtWorldPoint 4. ClearForce 2. 衝撃力 1. ApplyImpulse 2. ClearImpulse 3. ApplyAngularImpulse 3. トルク 1. ApplyTorque 2. ClearTorque フォースはボディを加速させるのに使用されます。ボディまたはボディ上の特定の点に適用することができます。これは、あなたのキャラクターに時間の経過とともに加速するジェットパックを追加するのに使用できます。 衝撃力はボディに衝撃を与えるのに使用されます。衝撃力は、フォースのようにボディを加速させる代わりに、ボディの速度を更新します。ゲームのキャラクターをジャンプさせるのにこれを使用することができます。ジャンプは、瞬時の変化であり、加速はしません。 トルクはボディのトルク (回転) として適用されます。ホイールを回転させるか、ボーダーに丘を駈け上がらせることができます。 [物理プロパティ] Farseer はボディとジオメトリの物理プロパティを変更するための素晴らしいインターフェースを持っています。ほとんどのプロパティは物理エンジン実行中に変更することができ、ダイナミックな振る舞いを作成することを可能にします。 以下に物理プロパティとどのようなものか簡単な説明を示します: Body クラスのプロパティ: AngularVelocity 回転速度はボディが回転している比率です。これはラジアン/秒で計測されます。比率を大きくするとボディが速く回転します。 LinearVelocity ベロシティは位置変更の比率として定義されます。また、ボディの単位時間の置き換えとしても定義されます。これは、ただ移動量を伝えるだけでなく、方向も含まれているベクトルです。 LinearDragCoefficient 抗力は、流体またはガス (空気) によってボディの動きに抵抗する力です。空気中を速く移動しているボディがあると抗力によって徐々に失速します。Farseer Physics では、媒体 (流体またはガス) をボディに入れることができないため、手動でボディの抗力係数を設定しなければなりません。高い抗力係数は、ボディを動かすためにより多くの力が必要で、それにより失速します。 RotationalDragCoefficientほとんど LinearDragCoefficient と同じですが、回転するときにもいくらかの抵抗があります。回転の抗力係数が 0 でボディを回転させると、永遠に回転し続けます。回転の抗力係数が高ければ高いほどボディの回転は速く失速します。 Moment of Inertia (MOI 2Dでボディの慣性モーメントは、どれくらい質量中心についてボディを回転させるのが難しいか (または難しくないか) を示すスカラー値です。 Geom クラスのプロパティ: RestitutionCoefficient 反発係数は衝撃による前後間の速度比です。反発係数に 1 を設定すると、完全な弾みを持ちます。(地面に跳ね返るボールをイメージして下さい) また、0 に設定すると、全く弾まなくなります。 FrictionCoefficient 摩擦力は、2つの物質面がお互いと接触して、運動に対して相対的に抵抗を与える基本的な力です。物質の摩擦力が大きくなると、他の物質と比較してより動きにくくなります。 例えば鋼の氷で、非常に小さい摩擦係数を持ちます。お互いにすぐに滑ってしまいます。一方、舗道の上のゴムは、非常に高い摩擦係数を持っており、ほとんど滑りません。 Farseer Physics は摩擦力を扱う2つの異なった方法がありますので注意して下さい。PhysicsSimulator オブジェクトの FrictionType に次の2つの内1つを設定して下さい。 ○ Average ジオメトリ (物質) の1つが摩擦係数 5 でもう一方が摩擦係数 3 のとき、平均の摩擦係数 4 になります。 ○ Minimum 2つのジオメトリ (物質) の内、低い方の摩擦係数になります。 2つの摩擦係数が 5 と 3 であれば、低い方の 3 になります。 Farseer Physics のデフォルトは Average です。 [Farseer の拡張] Farseer Physics Engine 2.0 から共通の作業の補助を行ういくつかの先進的なメソッドが含まれています。拡張は、物理学エンジンの振る舞いを変えないように高レベルの機能のみです。 [テクスチャからの頂点作成] Farseer Physics Engine 2.0 では、ポリゴン情報の格納されている uint[] 配列を検索し、位置をマッピングするアルゴリズムを含んでいます。これは人が自作のテクスチャからジオメトリを作成するのを簡単にします。 テクスチャから頂点を作成するアルゴリズムを使うには、以下のようにして下さい: //Load texture that will represent the physics body Texture2D polygonTexture = ScreenManager.ContentManager.Load Texture2D ("Content/Texture"); //Create an array to hold the data from the texture uint[] data = new uint[polygonTexture.Width * polygonTexture.Height]; //Transfer the texture data to the array polygonTexture.GetData(data); //Calculate the vertices from the array Vertices verts = Vertices.CreatePolygon(data, polygonTexture.Width, polygonTexture.Height); //Make sure that the origin of the texture is the centroid (real center of geometry) Vector2 polygonOrigin = verts.GetCentroid(); //Use the body factory to create the physics body Body polygonBody = BodyFactory.Instance.CreatePolygonBody(PhysicsSimulator, verts, 5); polygonBody.Position = new Vector2(500, 400); GeomFactory.Instance.CreatePolygonGeom(PhysicsSimulator, polygonBody, verts, 0); [パスジェネレーター] Farseer Physics Engine 2.0 では、パスジェネレーターと呼ばれるものを含んでいます。カーブ、ボディ間のジョイントまたはスプリングに沿ってボディを作成することができます。これは色々な場合で役に立ちます: ○ キャタピラを作る ○ ロープボディ ○ 鎖 少しだけ言及することがあります。 パスジェネレーターは Path クラス内にあり、ComplexFactory が鎖とロープを作成するときに使用します。パスジェネレーターを使用することで、制限を想像するだけで連結されたボディを作成します。パスジェネレーターに全てのボディのジオメトリを作成させることもできます。これは他のオブジェクトとの衝突を有効にします。 [パフォーマンス] パフォーマンスは多くのアプリケーションタイプで本当に重要です。しかし、開発が完了するまでは決して最適化すべきではありません。例えば開発の初期段階からマルチスレッドを導入すると、同期、ロッキング、条件の競合など多くの頭痛の種を持つことになってしまいます。 綺麗なコードを書き、コンパイラを信頼して仕事をすることは最も重要な事です。したがって、綺麗な設計は 1,000 マイクロ秒の最適化よりも遥かに重要です。 以下に、アプリケーションのパフォーマンスを向上させるいくつかの Tips とコツを示します: 1. 背景のチャンクアップ 広域な衝突判定は衝突チェックに AABB を使用しているので、一区画に大きな背景があると、常に背景全体を厳密な衝突判定の対象としてしまいます。これは大きなパフォーマンスダウンを引き起こします。 解決策として複数のチャンクに背景を作成し、現在プレーヤーが立っている領域だけを厳密な衝突のチェックをします。 Before: After: 2. シンプルなジオメトリ 上の背景画像で分かるように、点はカーブのトップを定義しており、アウトラインの全ての詳細を取得するのに必要です。 より多くの点、より大きな詳細。 これは、パフォーマンスの潜在的問題です。 Farseer Physics は高いパフォーマンスで計算するには点の数が少ないことが必要になるため、アウトラインの詳細を維持している間は点の総数を少なく保つことが正しい方法です。 もう一つ注意してほしいことは、プレイヤーが触れることがないのであれば、背景上には多くの点は必要ありません。そのため、底辺には少しも余分な点も置く必要はありません。 3. グリッドのセルサイズは大きく保つ 「グリッド」の章で記載しているように、グリッドはセルサイズを衝突判定の精度を決定するのに使用します。小さいグリッドのセルサイズは、より正確な衝突検出を意味しますが、計算するには長い時間がかかります。 最初にデフォルトサイズを渡すことで、正常なグリッドのセルサイズを手動で見つけることができます。(ジオメトリの AABB に必要な大きさの最小は 1/10 です。詳細情報は「既知の問題」の章の「Geometries going into each other」を見て下さい。)そして衝突に信頼性がなくなるまで大きくして下さい。 最適なグリッドのセルサイズを見つけることで、より良いパフォーマンスを与えることができますが、衝突に予測できない問題が起こるかもしれません。これはアプリケーションの開発が完了しているときのみに行うということを忘れないで下さい。 4. ボディ/ジオメトリの最小数 パフォーマンスを向上させる最も簡単で論理的な方法は、一度にアクティブになるボディとジオメトリの数を少なくすることです。もしマップが大きく、プレーヤーがもう一つの区画を開始するまでに長い間がかかるのであれば、プレーヤーが到着するまでの間、マップのその部分を非アクティブにしておくことができます。 これはいくつかのゲームで本当に簡単にできます。例えば、マップのある一定の場所をセンサーと見なすことができました。(注意:ジオメトリの IsSensor に true を設定して下さい)そしてプレーヤーがそのセンサーに達するとき、マップの次の部分をアクティブにします。 このような方法は多くあります。それは全て、あなたが開発しているゲームの種類に依存します。 5. キャッシング もう一つの非常に簡単な実装は、オブジェクトの高速交換キャッシングです。敵または弾丸を大量に量産しているのなら、敵/弾丸を作り上げるボディとジオメトリを事前に作成できます。 Farseer Physics はアービターにプール(キャッシュ)を使用して、その作成を大幅に高速化します。 このプールが実際はパブリックなので、オブジェクトをキャッシュするのに Farseer からジェネリックの Pool クラスを使用できます。 To create a pool of 10 soldiers, you could do something like this: Pool Enemy pool = new Pool Enemy (); for (int i = 0; i 100; i++) { Enemy enemy = new Enemy(EnemyType.Soldier, Health.100); pool.Insert(enemy); } そして、ゲーム中に兵士を必要とすると: Enemy enemy = pool.Fetch(); enemy.Shoot(); このようにプールがほしい理由が2つあります。そのうちの一つがガーベージコレクター、もう一つがインスタンスの事前作成です。 ガーベージコレクターは後片付けをします。しかしこれは、敵を作成し、Dispose() を実行することを意味します。ガーベージコレクターは敵が死ぬときにシステムメモリからそれを取り除きます。 しかし、プールの中に敵があれば、Dispose() を呼ぶ必要はありません。その敵を非アクティブにするだけです。(そして、敵を描画しません)これにより少しのガーベージコレクションで済みます。 インスタンスの事前作成も Farser Physics が距離グリッドと呼ばれているものを使う場合にとても有効です。このグリッドは、新しくジオメトリが作成されたときに計算されます。そしてそれはとても時間がかかることがあります。 そのため、ゲームを開始する(または、新しいマップをロードする)ときに、敵のプールを作成することで敵の作成時間を大きく高速化できます。 6. リリースモードでコンパイルすることを忘れないで下さい。 アプリケーションを公開リリースするときは、リリースモードに設定されているかどうかを確認してコンパイルして下さい。.net プラットホームは最初に C#/Vb.net コードを IL コード(中間コード) にコンパイルし、それから JIT(Just-In-Time コンパイラ) はそのコードをネイティブのマシン語にコンパイルし、アプリケーションを実行します。 リリース構成でアプリケーションをコンパイルするとき、生成された IL コードでは、JIT が IL を実行するとき、最適化を実行しなければならないとしています。 これはアプリケーションの速度を向上させ、またアプリケーションの全体的なサイズを減少させるかもしれません。 7. ベクトルと行列を参照で渡す XNA ではベクトル (Vector2, Vector3) と行列 (Matrix) は構造体または値型と呼ばれています. 値型がメソッドのパラメータとして渡されると、それはコピーされます。大きな行列または多くのベクトルがあると、コードを遅くすることになります。 ベクトルまたは行列を参照で渡すことによって、アプリケーションを少し高速化することができるかもしれません。 Farseer は特定の場所で値型渡しをサポートしており、例を下記に示します: Body body = BodyFactory.Instance.CreateCircleBody(PhysicsSimulator, 64, 1); Vector2 force = new Vector2(10,10); for (int i = 0; i 100; i++) { body.ApplyForce(ref force); } この例は ref キーワードを使い、100個の force ベクトルをコピーしています。これによりコードの何箇所かは、多くの恩恵を受けるかもしれません。 8. マルチスレッディング マルチスレッディングはとても手間のかかることで、正しく実装するのが困難な場合があります。マルチスレッド化によりゲームパフォーマンスが向上し、画面上に同時発生できるエレメントの数は少し向上します。実装の詳細はこのマニュアルの範囲外ですが、Farseer Physics Engine 2.0 はマルチスレッディングの例を含んでいます。詳細はサンプル(デモ4)を見て下さい。 9. 非アクティブコントローラー Farseer Physics Engine 2.0 は、非アクティブコントローラーと呼ばれている新しい機能を含んでいます。このコントローラーは、「休止ボディ」と呼ばれているものを有効にします。ゲームにほとんど動かないエレメントが多く含んでいる場合、それらをしばらくの間、非アクティブにすることによって、いくらかパフォーマンスを向上させることができます。 非アクティブコントローラーはこのためにあります。物理シミュレーターでそれを有効にし、いくつかの基本設定を行うだけです。詳細情報は「非アクティブコントローラー」の章を見て下さい。 10. スケーリング スケーリングは、Farseer Physics Engine 2.0 のもう一つの新機能です。ゲームが処理が集中しているところがあり、またフレームレートの低下(通常60fps)を許容できるのであれば、エンジンを少し減速し、後で再び速めさせることができます。 しなければならないことは、下記のようにスケーリングコントローラーをアクティブにするだけです: PhysicsSimulator.Scaling.Enabled = true; そして、MaximumUpdateInterval を設定して下さい。要求された更新レート のデフォルトは 0.001f、最大更新レートのデフォルトは 0.01fです。 11. 円 - 円 最適化 これは、レアケースの一つですが、誰かの役に立つかもしれません。 詳細情報はここにあります:Circle - Circle optimization コードを最適化する方法が他にも多くあります。 Farseer Physics 限定でないものについては詳細を述べませんが、ショートリストをここに記載します; 注意:このリストの項目は、小さな最適化に分類されており、本当にパフォーマンスが必要なクリティカルなコードでない限り使用されません。詳細は「Understanding XNA Framework Performance」を見て下さい。Farseer Physics Engine 2.0 はすでにこれらの最適化が行われています。 1. Inline performance critical methods Before: if (IsColorBlack(new Color(10, 4, 1))) { } private bool IsColorBlack(Color color) { return color == Color.Black; } After: if (new Color(10, 4, 1) == Color.Black) { 2. Inline vectors instead of referencing Before: Vector2 distance = Vector2.Zero; Vector2.Subtract(ref GeometryB.Body.Position, ref GeometryA.Body.position, out distance); After: Vector2 distance = Vector2.Zero; distance.X = GeometryB.Body.Position.X - GeometryA.Body.position.X; distance.Y = GeometryB.Body.Position.Y - GeometryA.Body.position.Y; 3. Inline constructors Before: Vector2 distance = new Vector2(10,10); After: Vector2 distance = new Vector2(); distance.X = 10; distance.Y = 10; [既知の問題] Farseer Physics に関する既知の問題がいくつかあります。これらの問題のいくつかは Farseer Physics だけでなく、他の多くの物理エンジンでも見られます。この問題はパフォーマンスやユーザビリティを犠牲せずに修正するのは簡単ではありません。 1. トンネリング オブジェクトが高速で移動するとき、壁にぶつかり内部で動けなくなるか、または衝突することなく突き抜ける現象が発生します。 Farseer Physics 2.0 は、現在、これの良い解決策を何も持っていません。しかしこれが起こるのを防ぐ CCD(Continuous Collision Detection) を実装する計画があります。 以下はその時までの選択肢になります: 1) オブジェクトを遅く動くようにする。 2) オブジェクトを大きくする。 3) タイムステップを小さくする。 4) Ray-casting を使う。 5) スイープ衝突検出(情報はここにあります) 6) マルチサンプリング 2. ジオメトリがお互いに入り込む これは原因が2つあります:ジオメトリは真っ直ぐなエッジでさえ、鋭い点または少なすぎる点を持っています。 鋭い点を持っているならば、デフォルトより小さいグリッドのサイズ値を使う必要があるかもしれません。デフォルトでは、CreatePolygonBody メソッドは collisionGridCellSize に 0 を渡すと、 AABB のサイズを元に collisionGridCellSize を計算します。 もし鋭い点を持ったジオメトリだとしたら、恐らくデフォルトより小さい値になります。0 でないの値を渡し、GeomFactory.GridCellSizeAABBFactor のプロパティを設定することによって、デフォルトの計算を調節することができます。 このプロパティはデフォルトの collisionGridCellSize を計算するのに使用されます。現在、.1 を設定すると、collisionGridCellSize にジオメトリの AABB の最小に必要な値の 1/10 を意味します。 他にできることとして、ジオメトリにより多くの点を挿入してみて下さい。Farseer Physics には、このためのヘルパーメソッドがあります。SubDivideEdges() と呼ばれており、Vertices クラスの中にあります。 下記に例を示します: Body rectBody = BodyFactory.Instance.CreateRectangleBody(128, 128, 1); Vertices vertices = new Vertices(); vertices.Add(new Vector2(-64, -64)); vertices.Add(new Vector2(64, -64)); vertices.Add(new Vector2(64, 64)); vertices.Add(new Vector2(-64, 64)); vertices.SubDivideEdges(10); Geom rectGeom = new Geom(rectBody, vertices, 11); 注意:ボディとジオメトリを物理シミュレーターに追加するのを忘れないで下さい。 Before SubDivideEdges() After SubDivideEdges() 3. センターへの描画 Farseer Physics Engine 1.0.0.4 からジオメトリファクトリーの CreatePolygonGeom メソッドが頂点の重心をセンターに取ることをサポートしています。このスレッドで説明されている方法に従うか、または CreatePolygonGeom メソッドで Vector2 のオフセットパラメータを使用して、動作させることができます。
https://w.atwiki.jp/kongregate/pages/69.html
Physics Pack Physics Pack Badges on Kongregateに載っているPhysics PackのBADGE一覧です。 BADGE名 ゲーム名
https://w.atwiki.jp/taziro/pages/49.html
[目次] <次ページ> 紹介 概要 ボディ ボディファクトリー ジオメトリ ジオメトリファクトリー 物理シュミレータービューア ジョイント レボリュートジョイント アングルジョイント アングルリミットジョイント ピンジョイント シリンダージョイント ジョイントファクトリー スプリング リニアスプリング アングルスプリング スプリングファクトリー [紹介] Farseer Physics Engine は簡単に使える2D物理エンジンです。XNA、Silverlight、WPF、Vanilla .NET といった幅広いプラットフォームをサポートしています。Farseer Physics Engine は簡単さ、便利さ、そして楽しくてダイナミックなゲームを作ることにフォーカスしています。 [概要] 簡単に説明しますと、Farseer Physics Engine はゲーム中の物体の経過時間によって位置と回転をコントロールするように設計されています。 現実世界では、物体はフォースとトルクによって移動と回転が起こります。Farseer でも同じです。現実世界の物体を「ボディ (剛体)」と呼ばれるオブジェクトで表します。フォースとトルクが適用されると、ボディは2D物理の法則によって作用します。ボディの位置と回転は、ゲーム中の物体を更新するために使用されます。 最もシンプルな手順は以下のようになります: 1. ボディを作成します。 2. シミュレーターにボディを追加します。 3. ゲームループを開始します。 1. ボディにフォースとトルクを適用します。 2. シミュレーターを更新します。 4. ゲームループを終了します。 ボディは設計上、2Dワールド上でジオメトリを持っていません。したがって衝突の概念がありません。 Farseer には、衝突を行うために「Geometry (ジオメトリ)」が用意されています。Geometry は頂点の集合で定義されます。ボディの形状を認識させるために、一つ以上の Geometry がアタッチされます。これでボディが他のボディと衝突することができます。(actually other Geometries attached to other Bodies, but you get the picture.) [ボディ] ボディは Farseer の中心的な物理オブジェクトです。フォース、トルク、衝撃力はボディに適用され、その動きに従ってボディに作用します。ボディは単独では衝突判定のための型を含みません。ボディを作成するには、通常 BodyFactory を使用します。しかし、最初ですので、下記にボディの作成手順を示します int mass = 1; float width = 128; float height = 128; Body rectBody = new Body(); rectBody.Mass = mass; rectBody.MomentOfInertia = mass * (width * width + height * height) / 12; rectBody.Position = new Vector2(100, 200); 長方形の MOI (慣性モーメント) は下記のように計算されます 各形状の MOI を覚えておけば、Farseer Physics があなたの代わりに MOI を計算してくれます。あなたがしなければならないことは「ボディファクトリー」の章に記載されている BodyFactory クラスを使用することだけです。ボディについて一つだけ注意してほしいことがあります。それはボディの位置はセンターからの相対位置に置かれるということです。 ノーマルポジション センターポジション これは位置決めと描画のコードに関係しています。ボディの位置を決めるとき、位置をセンターからの相対位置に置く必要があります。また、ボディを画面上に描画したいときも、センターからの相対位置に描画されることを確認して下さい。 [ボディファクトリー] ファクトリーからボディを作成するには下記のように記述します Body rectBody = BodyFactory.Instance.CreateRectangleBody(PhysicsSimulator, 128, 128, 1); このボディは幅 128、高さ 128 のサイズ、質量 1 です。MOI (慣性モーメント) が計算されます。引数に物理シミュレーターを渡すことで、ボディが直ちに追加されることに注意して下さい。 下記の型のボディがファクトリーから作成できます ○ Rectangle ○ Circle ○ Polygon ○ Body 最後の項目 (Body) は、Farseer に MOI を計算させずにボディを作成したいときのためにあります。また、ボディのクローンを作成し、それを使用することもできます。 BodyFactory には、いくつかオーバーロードされたメソッドがあります。物理シミュレーターを引数に取るものとそうでないものがあります。物理シミュレーターを渡すと、作成したボディがシミュレーターに追加されます。 [ジオメトリ] ジオメトリ (Farseer では「Geom」と呼ばれます) は衝突検出の核です。ジオメトリは、形状のエッジを定義するボディと頂点の集合(反時計回りに配置されます)を必要とします。 ボディはフォース、トルク、衝撃力をコントロールする間、ジオメトリは衝突検出をコントロールし、他のジオメトリとの衝突に関連する衝撃力を計算します。 ジオメトリを作成するには、通常 GeomFactory を使用します。しかし、最初ですので、下記に ジオメトリ の作成手順を示します: Body rectBody = BodyFactory.Instance.CreateRectangleBody(128, 128, 1); Vertices vertices = new Vertices();vertices.Add(new Vector2(-64, -64));vertices.Add(new Vector2(64, -64));vertices.Add(new Vector2(64, 64));vertices.Add(new Vector2(-64, 64)); Geom rectGeom = new Geom(rectBody, vertices, 11); ここでは長方形のボディを作成し、長方形 (0, 0 座標からの相対位置) のアウトラインを頂点の集合で表し、新しいジオメトリを頂点で定義します。Geom のコンストラクタの引数に渡された 11 はグリッドのセルサイズです。「グリッド」の章にグリッドのセルサイズについての詳細を記載しています。 [ジオメトリファクトリー] もう一つ GeomFactory を使ったもっと簡単なジオメトリの作成方法があります。GeomFactory は長方形や円などの単純な形状の頂点コレクションを作成できます。必要なものは長方形の幅と高さ、または円の半径だけです。 下記に GeomFactory を使用した Geom の作成例を示します: Body rectBody = BodyFactory.Instance.CreateRectangleBody(128, 64, 1); Geom rectGeom = GeomFactory.Instance.CreateRectangleGeom(PhysicsSimulator, rectBody, 128, 64); 頂点やグリッドのセルサイズは指定しなくて良いことに注目して下さい。GeomFactory は頂点を作成し、グリッドのセルサイズを自動計算します。しかし、グリッドのセルサイズをコントロールしたいこともあります。 これもまた、GeomFactory ではとても簡単に行えます。グリッドのセルサイズを引数に取るオーバーロードされたメソッドを使用するだけです: Geom rectGeom = GeomFactory.Instance.CreateRectangleGeom(PhysicsSimulator, rectBody, 128, 64, 6.4f); ここではグリッドのセルサイズを 6.4 としました。(C# では、数値の後ろについている「f」は float型であることを示します) グリッドのセルサイズに 0 を渡すと自動計算されます。ジオメトリの最も短い側面 (今回の例でいうと 64) を検索し、デフォルトのグリッドのセルサイズに 0.1 を掛けます。今回の例では 6.4 になります。 デフォルトのグリッドのセルサイズは、GeomFactory の GridCellSizeAABBFactor プロパティを設定することで調整できます。 [物理シュミレータービューア] 物理シミュレータービューアは、ジョイントのアンカー、ボディの位置、ジオメトリの整列、衝突をデバッグするために使用されます。ビューアがアクティブなとき、Farseer の物理が関係した問題をデバッグするのに不可欠なアンカー、衝突、接触点、中点、AABB、その他多くの情報を確認することができます。 物理シミュレータービューアは XNA のみで動作します。将来的には他のプラットフォームにも対応させる予定です。 デバッグビュー無し デバッグビュー有り 説明: デバッグビューには多くのコンフィギュレーションがあります。ここに可能性のリストがあります: パフォーマンスパネル ○ エンジンの更新タイミングやボディ、ジオメトリ、ジョイント、スプリング、コントローラー、アービターの現在の数などの情報を表示します。 ○ Clean up 最終更新でジオメトリ、ボディ、ジョイント、接触点、スプリングの追加、削除にかかった時間です。 ○ Broad Phase Collision 広域な衝突検出にかかった時間です。 ○ Narrow Phase Collision 厳密な衝突検出にかかった時間です。 ○ Apply Forces 全てのスプリング、コントローラー、ボディにフォースを適用するにかかった時間です。 ○ Apply Impulses ジョイントとアービターに衝撃力を適用するのにかかった時間です。 ○ Update Positions 全てのボディの位置を更新するのにかかった時間です。 頂点 ○ ジオメトリを形成する頂点を表示します。 ジオメトリの周りに小さな黒い点として表示されます。 AABB ○ Axis Aligned Bounding Box を表示します。「AABB」の章に詳細を記載しています) 接触点 ○ 接触点を表示します。小さな赤い点として表示されます。 座標軸 ○ ボディの中点を表示します。黒い+印で表示されます。 グリッド ○ 厳密な衝突検出に使用されるジオメトリのグリッドを表示します。グリッド内に多くの点が存在することがあるため、このオプションによって描画速度が低下するかもしれません。黒い点として表示されます。(上のデバッグ表示のスクリーンショットでは無効になっています) エッジ ○ ジオメトリのエッジのアウトラインを表示します。黒いエッジとして表示されます。 ジョイント ○ レボリュートジョイント、ピンジョイント、シリンダージョイントを視覚化します。 スプリング ○ リニアスプリング (固定バージョンと通常バージョンの両方) は2つの終点を結ぶ黒いラインで表示されます。直線上に配置される3つの点はラインの収縮と膨張を表すために表示されます。 [ジョイント] Farseer Physics Engine はいくつか基本的なジョイントを提供します。これらのジョイントを組み合わせることでほとんどのダイナミックな振る舞いを作成することができます: ○ レボリュートジョイント (1軸回転ジョイント) ○ アングルジョイント (回転ジョイント) ○ アングルリミットジョイント (制限付き回転ジョイント) ○ ピンジョイント ○ スライダージョイント ○ ギアジョイント ※実験中のジョイントです。 ※固定バージョンについて 固定バージョンとはジョイントがワールド上に固定され、他の非固定バージョンのジョイントとしてのボディには固定されないことを意味します。 全てのジョイントについての重要事項 ○ いくつかのジョイントはボディから相対位置のアンカーとワールド座標上のアンカーが必要になります。そして、使用時にはジョイントのタイプに注意して下さい。 ○ ジョイントはボディにアタッチされます。 ○ 全てのジョイントはいくつか共通の変数とメソッドがあります。 ○ アンカーはアタッチされたボディのジオメトリの内部にある必要はありません。 ○ ジョイントは壊れたとき、動作しなくなります。 ジョイントがうまく動作しないときは・・・ 1. アンカーが正しいかどうか確認して下さい。物理シミュレータービューアを使用し、それを確認して下さい。 2. プロパティを大きく変更しないで下さい。ゆっくり調整し、シミュレーションを再確認して下さい。 3. アンカーはアタッチされたボディのジオメトリの内部にある必要はありません。 ジオメトリの問題を解決する能力を制限しないで下さい。ゲームの50%はフェイクであることを覚えておいて下さい。最終結果が正しく"見える"ようにして下さい。 開発者情報 全てのジョイントは基底クラス Joint から派生しています。もしあなたが独自の制約を追加できるノウハウがあれば、必ず Joint から派生して下さい。 (また、それをコミュニティーと共有して下さい) 共通の変数 - (これらは全てのジョイントに適用されます) ○ Enabled - 単純に制約を行うかどうかをエンジンに知らせます。 ○ IsDisposed - ジョイントが破棄されたかどうかをあなたと物理シミュレーターに知らせます。 ○ JointError - ジョイントのエラーを取得します。全てのジョイントにエラーが生じる訳ではないので注意して下さい。 ○ Breakpoint - JointError がジョイントが壊れる前に達することのできる最大値を定義します。デフォルトでは壊れません。(浮動小数点数の最大値になっています) ○ Softness - この係数はジョイントの柔軟さを指定するのに使用されます。0.0 ~ 1.0 の間の値であるべきですが、それ以外は何も定義されていません。これはシミュレーターをあなたの好みに調整するためだけに使用されます。全てのジョイントは Softness に 0.0f を設定しても、いくらかの柔軟性を持っていることに注意して下さい。 ○ BiasFactor - この係数はどのくらいの強さでエラーを修正するかを決定します。0.0 ~ 1.0 の間の値であるべきですが、それ以外は何も定義されていません。デフォルト値は 0.2f です。高すぎる値、または低すぎる値を設定すると、動的に不安定な状態になることがありますので、小さな増減で変更するように注意して下さい。 ○ Broke - このイベントハンドラはジョイントが壊れたときに呼び出されます。ここにメソッドを提供するかどうかはあなた次第です。もし提供しなければ何も起こりません。○ Tag - あなたの好きなデータを設定できる共通オブジェクトです。 共通のメソッド - (これらは全てのジョイントに適用されます) ○ Validate - 関係している全てボディが破棄されていないかどうかを決定します。もしいずれかのボディが破棄されていたならば、ジョイントを破棄します。 ○ PreStep - ジョイントの更新に必要な数学計算を実行します。自身のジョイントが使用するものだけを記述して下さい。 ○ Update - ジョイントを更新します ○ Dispose - ジョイントを破棄します。 [レボリュートジョイント] このタイプのジョイントは、車輪を加えたり、複数のオブジェクトを結び付けるのに最適です。このジョイントは、ワールドベクトルで扱いますが、内部的にはジョイントの位置を2つのローカルベクトルとして保存しています。ジョイントのエラーは、2つのローカルベクトルの間の距離を見ることによって決定します。このジョイントはボディ本体と固定タイプのボディから成ります。ボディ本体を使うときは直線的に動くことができます。そして、固定タイプのボディを使うときは回転だけができることに注意して下さい。 プロパティ ○ Body1 - 最初のジョイントのボディを取得/設定します。このプロパティは固定レボリュートジョイントでは Body と名付けられています。 ○ Body2 - 2つ目のジョイントのボディを取得/設定します。このプロパティは固定レボリュートジョイントでは存在しません。 ○ Anchor - ジョイントのアンカーを取得/設定します。これはワールド座標上にあります。 ○ CurrentAnchor - シミュレーション開始後のジョイントのワールド座標上の位置を取得します。 ジョイントを描画するときに役立ちます。 ○ SetInitialAnchor - シミュレーション開始前のアンカーを設定します。 デモを表示 デモの説明: 黄色の長方形はレボリュートジョイントでその場所に止められています。移動することはできず、回転しかできません。マウスを使って長方形を回転させてみて下さい。固定レボリュートジョイントはこれを実現するために使用されます。 次の長方形を見て下さい。緑色の長方形が赤色の長方形に止められているのが分かると思います。それらはワールド上を動き回ることはできますが、お互いに相対位置にあり回転しかできません。通常、レボリュートジョイントはこれを実現するために使用されます。 [アングルジョイント] このジョイントは2つの繋がったボディの角度を同じにする、または目的の角度にするのに最適な動作をします。固定バージョンは単純にボディが目的の角度に保たれます。スナップの角度を元にすることなく、プログラム的にボディの角度を変更するのに最適な動作をします。角度を変更するとボディが素早く反応し、その角度に達します。 プロパティ ○ TargetAngle - ボディが目指す角度 (ラジアン) を取得/設定します。 ○ MaxImpulse - ボディが TargetAngle を目指すときに使用する最大トルクを取得/設○ デフォルトでは浮動小数点数の最大値になっています。 ○ Body1 - 最初のジョイントのボディを取得/設定します。このプロパティは固定アングルジョイントで Body と名付けられています。 ○ Body2 - 2つ目のジョイントのボディを取得/設定します。このプロパティは固定アングルジョイントでは存在しません。 デモを表示 デモの説明: 左側に常に同じ角度に保たれている緑色の長方形があります。回転はできず、移動できるだけです。固定アングルジョイントはこれを実現するために使用されます。 右側に同じ角度/回転を共有している2つの黄色の長方形があります。一方を回転させると、もう片方も同じだけ回転します。通常、アングルジョイントはこれを実現するために使用されます。 [アングルリミットジョイント] アングルジョイントと同じですが、制限機能があり、また目的の角度、トルク、衝撃力がありません。 プロパティ ○ LowerLimit - ボディの最小角度 (ラジアン) を取得/設定します。 ○ UpperLimit - ボディの最大角度 (ラジアン) を取得/設定します。 ○ Slop - 制限の最小/最大に許す誤差を取得/設定します。 ○ Body1 - 最初のジョイントのボディを取得/設定します。このプロパティは固定アングルリミットジョイントでは Body と名付けられています。 ○ Body2 - 2つ目のジョイントのボディを取得/設定します。このプロパティは固定アングルリミットジョイントでは存在しません。 デモを表示 デモの説明: 左側の緑色の長方形は、常に定義された制限内で回転します。最小 15 度、最大 50 度です。固定アングルリミットジョイントはこれを実現するために使用されます。 2つの黄色の長方形は、常にお互いに指定された角度が制限されています。それらの両方を地面に置いてみて下さい。そうすれば、両方を地面にしっかり置くことが不可能であることが分かるでしょう。最小 15 度、最大 50 度です。通常、アングルリミットジョイントはこれを実現するために使用されます。 [ピンジョイント] このジョイントは恐らくロッドジョイントと呼ばれているでしょう。2つのボディが回転している間、その間の距離を保ちます。 プロパティ ○ TargetDistance - 2つのアンカー間の望ましい距離を取得/設定します。 距離を指定しない場合、ボディ間のオフセットは目標距離になります。 ○ Body1 - 最初のジョイントのボディを取得/設定します。再計算をせずに TargetDistance を変更すると動作が不安定になるかもしません。 ○ Body2 - 2つ目のジョイントのボディを取得/設定します。再計算をせずに TargetDistance を変更すると動作が不安定になるかもしません。 ○ Anchor1 - Body1 のローカル座標上のアンカーを取得/設定します。 ○ Anchor2 - Body2 のローカル座標上のアンカーを取得/設定します。 ○ WorldAnchor1 - Body1 のワールド座標上のアンカーを取得します。ジョイントを描画するときに役立ちます。 ○ WorldAnchor2 - Body2 のワールド座標上のアンカーを取得します。ジョイントを描画するときに役立ちます。 デモを表示 デモの説明: 2つの赤色の長方形は、互いの間の目標距離を保つために、ピンジョイントを使用しています。それらは互いにそれ以上、離れたり近づいたりできません。両方のボディは回転することはできます。 2つの黄色の長方形は、互いが最小から最大の間の距離を保つために、スライダージョイント (後述) を使用しています。そららはピンジョイントと比較し、お互いに離れたり近づいたりできます。 [シリンダージョイント] このジョイントはピンジョイントと似ていますが、距離の制限に最小/最大があります。2つのボディが回転している間、最小から最大の間の距離を保ちます。 プロパティ ○ TargetDistance - 2つのアンカー間の望ましい距離を取得/設定します。 ○ Body1 - 最初のジョイントのボディを取得/設定します。再計算をせずに TargetDistance を変更すると動作が不安定になるかもしません。 ○ Body2 - 2つ目のジョイントのボディを取得/設定します。再計算をせずに TargetDistance を変更すると動作が不安定になるかもしません。 ○ Anchor1 - Body1 のローカル座標上のアンカーを取得/設定します。 ○ Anchor2 - Body2 のローカル座標上のアンカーを取得/設定します。 ○ WorldAnchor1 - Body1 のワールド座標上のアンカーを取得します。ジョイントを描画するときに役立ちます。 ○ Min - アンカーが近づけられる最小の距離を取得/設定します。 ○ Max - アンカーが離れられる最大の距離を取得/設定します。 ○ Slop - 制限の最小/最大に許す誤差を取得/設定します。 [ジョイントファクトリー] ジョイントファクトリーはボディファクトリーとほとんど同じ方法でジョイントを作成できます。 全てのパラメータはそれぞれのジョイントで説明してありますので、単純に使用されるそれぞれのメソッドのリストを記載します。ファクトリーはいつもジョイントの全てのパラメータが必要な訳ではないことに気を付けて下さい。 Revolute Joint Factory 1. CreateRevoluteJoint(PhysicsSimulator physicsSimulator, Body body1, Body body2, Vector2 initialAnchorPosition) 2. CreateRevoluteJoint(Body body1, Body body2, Vector2 initialAnchorPosition) Fixed Revolute Joint Factory 1. CreateFixedRevoluteJoint(PhysicsSimulator physicsSimulator, Body body, Vector2 anchor) 2. CreateFixedRevoluteJoint(Body body, Vector2 anchor) Pin Joint Factory 1. CreatePinJoint(PhysicsSimulator physicsSimulator, Body body1, Vector2 anchor1, Body body2, Vector2 anchor2) 2. CreatePinJoint(Body body1, Vector2 anchor1, Body body2, Vector2 anchor2) Slider Joint Factory 1. CreateSliderJoint(PhysicsSimulator physicsSimulator, Body body1, Vector2 anchor1, Body body2, Vector2 anchor2, float min, float max) 2. CreateSliderJoint(Body body1, Vector2 anchor1, Body body2, Vector2 anchor2, float min, float max) Angle Joint Factory 1. CreateAngleJoint(PhysicsSimulator physicsSimulator, Body body1, Body body2) 2. CreateAngleJoint(Body body1, Body body2) 3. CreateAngleJoint(PhysicsSimulator physicsSimulator, Body body1, Body body2, float softness, float biasFactor) 4. CreateAngleJoint(Body body1, Body body2, float softness, float biasFactor) Fixed Angle Joint Factory 1. CreateFixedAngleJoint(PhysicsSimulator physicsSimulator, Body body) 2. CreateFixedAngleJoint(Body body) Angle Limit Joint Factory 1. CreateAngleLimitJoint (PhysicsSimulator physicsSimulator, Body body1, Body body2, float min, float max) 2. CreateAngleLimitJoint (Body body1, Body body2, float min, float max) Fixed Angle Limit Joint Factory 1. CreateFixedAngleLimitJoint (PhysicsSimulator physicsSimulator, Body body, float min, float max) 2. CreateFixedAngleLimitJoint (Body body, float min, float max) [スプリング] Farseer Physics Engine はいくつか基本的なスプリングを提供します。これらのスプリングを組み合わせることでほとんどのダイナミックな振る舞いを作成することができます。 ○ リニアスプリング (線形スプリング) ○ アングルスプリング (回転スプリング) ※固定バージョンについて 固定バージョンとはスプリングがワールド上に固定され、他の非固定バージョンのスプリングとしてのボディには固定されないということを意味します。 全てのスプリングについての重要事項 ○ いくつかのスプリングはボディから相対位置のアンカーとワールド座標上のアンカーが必要になります。そして、使用時にはスプリングのタイプに注意して下さい。 ○ スプリングはボディにアタッチされます。 ○ 全てのスプリングはいくつか共通の変数とメソッドがあります。アンカーはアタッチされたボディのジオメトリの内部にある必要はありません。 ○ スプリングは壊れたとき、動作しなくなります。 スプリングがうまく動作しないときは・・・ 1. アンカーが正しいかどうか確認して下さい。物理シミュレータービューアを使用し、それを確認して下さい。 2. プロパティを大幅に変更しないで下さい。ゆっくり調整し、シミュレーションを再確認して下さい。 3. アンカーはアタッチされたボディのジオメトリの内部にある必要はありません。ジオメトリの問題を解決する能力を制限しないで下さい。ゲームの50%はフェイクであることを覚えておいて下さい。最終結果が正しく"見える"ようにして下さい。 開発者情報: 全てのスプリングは基底クラス Spring から派生しています。もしあなたが独自の制約を追加できるノウハウがあれば、必ず Spring から派生して下さい。(また、それをコミュニティーと共有して下さい) 共通の変数 - (これらは全てのスプリングに適用されます) ○ Enabled - 単純に制約を行うかどうかをエンジンに知らせます。 ○ IsDisposed - スプリングが破棄されたかどうかをあなたと物理シミュレーターに知らせます。 ○ DampningConstant - スプリングのダンプニング定数を取得/設定します。これは衝撃吸収装置のような働きをします。 ○ SpringConstant - スプリングの押し引き定数を取得/設定します。バネの強さと考えることができます。 ○ SpringError - スプリングのエラーを取得します。全てのスプリングにエラーが生じる訳ではないので注意して下さい。 ○ Breakpoint - JointError がジョイントが壊れる前に達することのできる最大値を定義します。 ○ Broke - このイベントハンドラはジョイントが壊れたときに呼び出されます。ここにメソッドを提供するかどうかはあなた次第です。もし提供しなければ何も起こりません。 ○ Tag - あなたの好きなデータを設定できる共通オブジェクトです。 共通のメソッド - (これらは全てのスプリングに適用されます) ○ Validate - 関係している全てボディが破棄されていないかどうかを決定します。もしいずれかのボディが破棄されていたならば、スプリングを破棄します。 ○ Update - スプリングを更新します。※原文の誤り? ○ Dispose - スプリングを破棄します。 [リニアスプリング] このスプリングはボディの押し引きを提供します。押したり引いたりすることができ、またあらゆる方向に働かせることができます。正しいジョイントと結合されれば、何でもシミュレートできます。 プロパティ ○ Body1 - 最初のスプリングのボディを取得/設定します。このプロパティは固定リニアスプリングでは Body と名付けられています。※原文の誤り? ○ Body2 - 2つ目のスプリングのボディを取得/設定します。このプロパティは固定リニアスプリングでは存在しません。※原文の誤り? ○ Anchor1 - Body1 のローカル座標上のアンカーを取得/設定します。 ○ Anchor2 - Body2 のローカル座標上のアンカーを取得/設定します ○ RestLength - これはバネが全く押し引きしていないときの長さです。ファクトリーを使用するとき、RestLength はアンカーとの間の距離として計算されることに注意して下さい。スプリングの作成してすぐに押し引きを開始したいのであれば、このプロパティを測っておくべきです。大きすぎる値だとボディが離れてしまい、小さすぎる値だとボディがくっついてしまいます。 デモを表示 デモの説明: 2つの黄色のボディがリニアスプリングでくっついています。ボディは大きなフォースで離すことができます。そららはゴムバンドのように繋がっています。 通常、リニアスプリングはこのデモのように使用されます。 このマニュアルの全てのデモは、ボディを動かしたりフォースを適用するために、固定リニアスプリングを使用しています。これは黒いのラインで表されています。 [アングルスプリング] このスプリングはねじり棒のように働きます。 プロパティ ○ Body1 - 最初のスプリングのボディを取得/設定します。このプロパティは固定リニアスプリングでは Body と名付けられています。 ○ Body2 - 2つ目のスプリングのボディを取得/設定します。このプロパティは固定リニアスプリングでは存在しません。 ○ TargetAngle - 目指す角度 (ラジアン) はスプリングの中心に置かれ、フォースは提供しません。 ○ MaxTorque - これは TargetAngle を目指すときに適用される最大トルクです。 ○ TorqueMultiplier - トルクにこの値が掛けられます。1.0f が通常のトルクです。デフォルト値は 1.0f です。 デモを表示 デモの説明: 中央の白いエレメントはまさしく飛込み板のように機能します。このアングルスプリングは固定タイプです。これはワールドにアタッチされていることを意味します。レボリュートジョイントは、スプリング板をワールド上に止めるのに使われています。そのため、同じ位置に留まっていますが、中心点の周りを回転することができます。 [スプリングファクトリー] スプリングファクトリーはボディファクトリーとほとんど同じ方法でスプリングを作成できます。全てのパラメータはそれぞれのスプリングで説明してありますので、単純に使用されるそれぞれのメソッドのリストを記載します。ファクトリーはいつもスプリングの全てのパラメータが必要な訳ではないことに気を付けて下さい。 Linear Spring Factory ○ CreateLinearSpring(PhysicsSimulator physicsSimulator, Body body1, Vector2 anchor1, Body body2, Vector2 anchor2, float springConstant, float dampningConstant) ○ CreateLinearSpring(Body body1, Vector2 anchor1, Body body2, Vector2 anchor2, float springConstant, float dampningConstant) Fixed Linear Spring Factory ○ CreateFixedLinearSpring(PhysicsSimulator physicsSimulator, Body body, Vector2 anchor1, Vector2 anchor2, float springConstant, float dampningConstant) ○ CreateFixedLinearSpring(Body body, Vector2 anchor1, Vector2 anchor2, float springConstant, float dampningConstant) Angle Spring Factory ○ CreateAngleSpring(PhysicsSimulator physicsSimulator, Body body1, Body body2, float springConstant, float dampningConstant) ○ CreateAngleSpring(Body body1, Body body2, float springConstant, float dampningConstant) Fixed Angle Spring Factory ○ CreateFixedAngleSpring(PhysicsSimulator physicsSimulator, Body body, float springConstant, float dampningConstant) ○ CreateFixedAngleSpring(Body body, float springConstant, float dampningConstant) <次ページ>
https://w.atwiki.jp/udk_tips/pages/51.html
概要 UDKに最初から入っているPhysicsGunにモデルなどを設定してみました。 適当に作った物なので細かい設定とかはまったくしていません、興味のある方は改変して使ってください。 ダウンロード http //www20.atwiki.jp/udk_tips/pub/PhysicsGun.zip その他 PhysicsGunはデフォルトで有効になっていますが、設定を変えたい場合はUTGame.ucのbGivePhysicsGun=で変更できます。 名前 コメント ~
https://w.atwiki.jp/physlab2014calc/pages/5.html
計算機班とは? コンピュータを用いて物理現象のシュミレーションをします。C言語はじめ、個人が得意なプログラミング言語を用いてプログラムを書いています。プログラムは「数値計算」と「描画」をします。描画ソフトはOpenGLなどを利用しています。最も大切なのは数値計算ですが、Physics Lab.は一般客に見せることが目的なので描画もついでに勉強しちゃうわけです。 物理学における計算機の立場 物理学の研究は「理論」と「実験」に分けられることが多くありますが、実際の研究者の中には第3 極として「コンピュータシュミレーション」を専門的に扱っている方もいます。現実的には、理論の検 証や実験前の見積もりに計算機を使うことも多く、理論・実験でも重要なスキルといえます。 テーマ 人に「見せる」プログラミング (グラフィックを念頭においたプログラミングをしましょう。もちろん研究段階では必ずしも可視化しなくていいですが) 参考になるかもしれない文献たち 「GLUTによるOpenGL入門」/床井浩平/工学社/1900円+税 →これは本ですが、下の「GLUTによる手抜きOpenGL入門」なら無料で手に入ります。必要なとこだけやればいいと思います。 「GLUTによる手抜きOpenGL入門」/http //www.wakayama-u.ac.jp/~tokoi/opengl/libglut.html#3.3/http //www.ie.u-ryukyu.ac.jp/~e085739/c.opengl.kumamoto.html 「パソコンで宇宙物理学 計算宇宙物理学入門」/ポール・ヘリングス/国書刊行会 →制限3体問題から彗星の話、銀河モデル・恒星モデル・宇宙モデルなど。 「宇宙物理学シュミレーション」/Danby・Kouzes・Whitney/海文堂 →多体問題、銀河、恒星の話など 「計算物理学」/J.M.ティッセン/丸善出版 →「モンテカルロ法による量子力学」などなど結構難しいの扱ってる。
https://w.atwiki.jp/physlab2014calc/pages/9.html
ミニポスターについて ・ポスターとは? ポスターは、当日来場して下さるお客さんに対して、研究成果を紙面上で発表するためのものです。 ポスターには、「概要」「目的」「手段」「結果」「考察」などを簡潔に分かりやすく書きます。 五月祭当日は、パソコンを並べて展示するわけですが、常に全員がいるわけではないので、自分のプログラムに対して説明書きを残しておく必要があります。そうすれば、お客さんに読んでもらったり、他の班員が代わりに説明したりできますね。特に、パソコンを普段触らない一般の人にも分かりやすくするためには、それくらいの配慮は最低限したいものです。 説明書には「プログラムの触り方(見方)」「物理的な説明」を加えて下さい。「手段」も加えて構いませんし、んまぁ皆さん好きなように作って下さい。 ・書くべき内容 ①どんな物理なのか紹介する 高校生でもわかるように簡単な言葉で書くようにしてください。今回のPhysics Lab.で部屋(201a)に掲示するポスターの最終案を載せておいたので、これくらいのレベルにあわせて下さい。画像が貼付けてあるとよいです。 ※このページの一番下に画像が置いてあります。見てみて下さい。 ②プログラムの遊び方・使い方などを書いておく そもそもプログラムを一般の人がすぐに使える状態にしておくのが望ましいです。 例えば、「ENTER KEY…開始、UP KEY/DOWN KEY…速度を変える、r…リセット」 みたいな感じです。実際には計算機班のメンバーがそばにいるので、少なくとも他の班員がわかるくらいにしておいて下さい。 ③プログラム名とプログラムの保存場所とコンパイルの方法(班員向け)←簡潔に! 何かしらの原因でウィンドウが閉じてしまった時に、プログラムを作成した本人がいないと困るので、実行ファイル名(またはプログラム名)とその場所(絶対パス)を書いておいて下さい。とりあえず、プログラムが実行できる方法が載っていれば何でもOKです。コンパイルが終わって、もういじる必要がないようにしておくとよいです。 例1… /Users/TakashiKojima/Desktop/計算機班/mag_field/mag (実行ファイル) 例2… /Users/TakashiKojima/Desktop/N_body/N_body/N_body.xcodeproj (Xcode) 例1は実行ファイルの置き場所を指定しており、実行ファイルをクリックするだけで動くようになっている場合です。 例2はXcodeを使って実行する場合です。 他にも、動画・画像としてまとめている場合はその動画の場所を指定して下さい。 ・分量は? A4が2枚分、つまりA3サイズ1枚分(片面)以内におさめてください。 ・期限は? 直前の週で印刷にこぎ着けたいので、5月12日(月)くらいには出来上がっていたいものです。
https://w.atwiki.jp/biones/pages/16.html
すべての自然科学の基礎となる物理学。 現代物理では、量子論と相対論の2本柱が基礎ですが、教育的観点から、古典力学と古典電磁気学もやります。 初等物理数学 古典力学 古典電磁気学 熱力学 特殊相対性理論 量子力学 統計力学 一般相対性理論 場の量子論 素粒子論
https://w.atwiki.jp/csjake/pages/102.html
Physis 2 スクリーンショット 内容 Physisの続編、以前のマップにもう1つ小島が加えられている。 無重力場やドミノ倒し等いくつかの新しいギミック有り。 評価 ボリューム ★★☆☆☆ デザイン ★★★☆☆ 面白さ ★★★☆☆ 難易度 ★☆☆☆☆ ダウンロード(1.7MB) Crymod
https://w.atwiki.jp/csjake/pages/147.html
Physis 3 スクリーンショット 内容 物理演算ギミックマップ、Physisシリーズ第三弾。 前作までの内容にロープ関係の仕掛けが複数追加されている。 評価 ボリューム ★★☆☆☆ デザイン ★★★☆☆ 面白さ ★★★☆☆ 難易度 ☆☆☆☆☆ ダウンロード(2.4MB) Crymod
https://w.atwiki.jp/schain/pages/36.html
PHYSICAL能力者 「竜や妖精など、架空の生物(幻獣)の魂が溶け込んだ者」についてこう呼びます。 「トリガー」 PHYSICAL能力者は、「トリガーを引く事」によって能力を発現します。 トリガーとは引き金の事であり、「トラウマを思い出す」などの精神的なきっかけや「ある食物を口にする」などの身体的なきっかけの事もあります。 PHYSICAL能力者の「能力」 PHYSICAL能力者はトリガーを引く事により、「自身の身体の一部を幻獣に変化させる」事ができます。 能力の性質は魂に溶け込んだ幻獣に深く由来しますが、発現後の姿であっても一般人から見たらただの人です。