简体   繁体   English

计算包含旋转的框的边界

[英]Calculate bounds of a box including rotation

在此输入图像描述

I am working on collision system for my game that uses custom colliders. 我正在为我的游戏使用自定义碰撞器的碰撞系统。 I used this to create bounding box for collisions. 我用来创建碰撞的边界框。

I am getting problem for the boxes where right and forward values have been used to create box. 我正在使用右侧和前方值用于创建框的框出现问题。 Otherwise its working fine. 否则它的工作正常。 Anybody has any idea how to include right and forward vectors in calculating 8 points for the cube. 任何人都知道如何在计算多维数据集的8个点时包含正向和向前矢量。

Below is my code for calculating points: 以下是我计算积分的代码:

 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
 }

Box is changing its position when i apply quaternion to transform 当我应用四元数进行转换时,Box正在改变它的位置

You'd need to concatenate the box's orientation (stored as Right and Forward) to the world transform. 您需要将框的方向(存储为右和前)连接到世界变换。 Something like this should probably work: 这样的事情应该可行:

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

(since Unity is annoyingly left-handed, you might have to fiddle with signs and the concatenation order a bit, or perhaps use rt instead of fwd in SetLookRotation) (因为Unity令人讨厌左撇子,你可能不得不摆弄标志和连接顺序,或者在SetLookRotation中使用rt而不是fwd)

Update: following a discussion in chat, this seems to be the final working version. 更新:在聊天讨论后,这似乎是最终的工作版本。

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);

Let's redefine this problem in terms of classes that are available natively within Unity3D's framework. 让我们根据Unity3D框架中本机可用的类重新定义这个问题。 If you understand the math well enough, you can take that and adapt it to these other classes that you're using. 如果你足够了解数学,你可以采用它并使其适应你正在使用的其他类。

If all you need is an axis-aligned bounding box (or AABB), then you can easily get that from any Renderer or Collider through their respective bounds properties. 如果您只需要一个轴对齐的边界框 (或AABB),那么您可以通过各自的bounds属性轻松地从任何RendererCollider Renderer获取该边界框 That's a quick solution that will suffice in many cases. 这是一个快速的解决方案,在许多情况下就足够了。

Some other bounding boxes are expressed in local space -- for example, a Mesh has a bounds property that's in local space. 其他一些边界框在局部空间中表示 - 例如, Mesh具有局部空间中的bounds属性。 For whatever reason, you will sometimes have a box that is some size up, right, and forward, and you may need to transform the points of that box into world space. 无论出于何种原因,您有时会有一个向上,向右和向前的大小的盒子,您可能需要将该盒子的点转换为世界空间。

Let's say our box looks like this: 假设我们的盒子看起来像这样:

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

Suppose we have a unit cube centered at zero: 假设我们有一个以零为中心的单位立方体:

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

The box's extents are half of its size: 盒子的范围是它的大小的一半:

Vector3 extents = size * 0.5f;

That makes it easy enough to calculate the eight points around the box: 这样可以很容易地计算出盒子周围的八个点:

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);

These points are all in local space, still. 这些点仍然在当地空间。 We just need a transform component to convert them into world space: 我们只需要一个transform组件将它们转换为世界空间:

for (int i=0; i<8; i++) {
    points[i] = transform.TransformPoint(points[i]);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM