3

ここに画像の説明を入力

カスタムコライダーを使用するゲームの衝突システムに取り組んでいます。これを使用して、衝突のバウンディング ボックスを作成しました。

ボックスの作成に right と forward の値が使用されているボックスで問題が発生しています。それ以外の場合は正常に動作します。立方体の 8 ポイントを計算する際に、右方向と前方方向のベクトルを含める方法を知っている人は誰でもいます。

以下は、ポイントを計算するための私のコードです。

 public static void GetBoundsPointsNoAlloc(BoxRegion bx, Matrix4x4 colliderBox4x4,Vector3[] points, Matrix4x4 mx) {
 Transform tr = Utils.FromMatrix4x4(ref DebugCollisionTestSphere.trans,mx);

 Vector3 v3Center = bx.center;
 Vector3 v3ext = bx.GetExtents();
 Vector3 right = bx.right;
 Vector3 forw = bx.forward;

   //Quaternion qua =Quaternion.LookRotation(bx.forward,Vector3.Cross     (bx.forward, bx.right));

   //tr.TransformDirection (bx.forward);
   //tr.localRotation = qua;
   tr.forward = bx.forward;
   tr.right =   bx.right;
   //tr.rotation = qua;

 points [0] = tr.TransformPoint (new Vector3 (v3Center.x - v3ext.x, v3Center.y + v3ext.y, v3Center.z - v3ext.z));  // Front top left corner
 points [1] = tr.TransformPoint (new Vector3 (v3Center.x + v3ext.x, v3Center.y + v3ext.y, v3Center.z - v3ext.z));  // Front top right corner
 points [2] = tr.TransformPoint (new Vector3 (v3Center.x - v3ext.x, v3Center.y - v3ext.y, v3Center.z - v3ext.z));  // Front bottom left corner
 points [3] = tr.TransformPoint (new Vector3 (v3Center.x + v3ext.x, v3Center.y - v3ext.y, v3Center.z - v3ext.z));  // Front bottom right corner
 points [4] = tr.TransformPoint (new Vector3 (v3Center.x - v3ext.x, v3Center.y + v3ext.y, v3Center.z + v3ext.z));  // Back top left corner
 points [5] = tr.TransformPoint (new Vector3 (v3Center.x + v3ext.x, v3Center.y + v3ext.y, v3Center.z + v3ext.z));  // Back top right corner
 points [6] = tr.TransformPoint (new Vector3 (v3Center.x - v3ext.x, v3Center.y - v3ext.y, v3Center.z + v3ext.z));  // Back bottom left corner
 points [7] = tr.TransformPoint (new Vector3 (v3Center.x + v3ext.x, v3Center.y - v3ext.y, v3Center.z + v3ext.z));  // Back bottom right corner
 }

クォータニオンを適用して変換すると、ボックスの位置が変化する

4

2 に答える 2

3

ボックスの向き (Right および Forward として保存) をワールド トランスフォームに連結する必要があります。このようなものはおそらくうまくいくはずです:

Vector3 fwd=bx.forward.normalized(), rt=br.right.normalized(), up=fwd.Cross(rt);
Quaternion qbox; qbox.SetLookRotation(fwd,up);
tr.rotation = tr.rotation*qbox;

(Unity は厄介なほど左利きなので、符号と連結順序を少しいじるか、SetLookRotation で fwd の代わりに rt を使用する必要があるかもしれません)

更新: チャットでの議論の後、これが最終的な作業バージョンのようです。

Quaternion quat = Quaternion.identity; 
quat.SetLookRotation(bx.forward, Vector3.Cross(bx.forward,bx.right)); 
points[0] = mx.MultiplyPoint3x4(quat * new Vector3(-bx.width/2,+bx.height/2,-bx.depth/2)+bx.center); 
...
points[7] = mx.MultiplyPoint3x4(quat * new Vector3(+bx.width/2,-bx.height/2,+bx.depth/2)+bx.center);
于 2015-11-27T12:01:31.997 に答える
1

Unity3D のフレームワーク内でネイティブに利用できるクラスの観点から、この問題を再定義しましょう。数学を十分に理解している場合は、それを使用して、使用している他のクラスに適応させることができます。

軸に沿ったバウンディング ボックス(または AABB)だけが必要な場合は、任意のプロパティから、RendererまたはColliderそれぞれのプロパティを介して簡単に取得できboundsます。これは、多くの場合で十分な迅速な解決策です。

他のいくつかのバウンディング ボックスはローカル スペースで表現されます。たとえば、 にMeshboundsローカル スペースのプロパティがあります。なんらかの理由で、ボックスのサイズが上、右、および前方にある場合があり、そのボックスのポイントをワールド空間に変換する必要がある場合があります。

ボックスが次のようになっているとします。

       size.x
   .+------+
 .' |    .'|
+---+--+'  | size.y      (all around some point 'center')
|   |  |   |
|  ,+--+---+
|.'    | .' size.z 
+------+'   

中心がゼロの単位立方体があるとします。

Vector3 center = Vector3.zero;
Vector3 size = Vector3.one;

ボックスの範囲は、そのサイズの半分です。

Vector3 extents = size * 0.5f;

これにより、ボックスの周りの 8 つのポイントを簡単に計算できます。

Vector3[] points = new Vector3[8];
points[0] = center + new Vector3( extents.x,  extents.y,  extents.z);
points[1] = center + new Vector3( extents.x,  extents.y, -extents.z);
points[2] = center + new Vector3( extents.x, -extents.y,  extents.z);
points[3] = center + new Vector3( extents.x, -extents.y, -extents.z);
points[4] = center + new Vector3(-extents.x,  extents.y,  extents.z);
points[5] = center + new Vector3(-extents.x,  extents.y, -extents.z);
points[6] = center + new Vector3(-extents.x, -extents.y,  extents.z);
points[7] = center + new Vector3(-extents.x, -extents.y, -extents.z);

これらのポイントはすべてローカル空間にあります。transformそれらをワールド空間に変換するためのコンポーネントが必要なだけです。

for (int i=0; i<8; i++) {
    points[i] = transform.TransformPoint(points[i]);
}
于 2015-11-18T06:25:04.070 に答える