C#实现OBB碰撞算法
作者:互联网
向量类Vec3
public class Vec3 { public float X { get; set; } public float Y { get; set; } public float Z { get; set; } public Vec3() { } public Vec3(float _x,float _y,float _z) { X = _x; Y = _y; Z = _z; } #region 操作符 public static Vec3 operator ^(Vec3 num1, Vec3 num2) { Vec3 v = new Vec3(); v.X = num1.Y * num2.Z - num1.Z * num2.Y; v.Y = num1.Z * num2.X - num1.X * num2.Z; v.Z = num1.X * num2.Y - num1.Y * num2.X; return v; } public static Vec3 operator -(Vec3 num1, Vec3 num2) { Vec3 v = new Vec3(); v.X = num1.X-num2.X; v.Y = num1.Y - num2.Y; v.Z = num1.Z - num2.Z; return v; } public static float operator *(Vec3 num1, Vec3 num2) { return num1.X* num2.X + num1.Y* num2.Y+ num1.Z* num2.Z; } public static Vec3 operator *(Vec3 num1, float num2) { Vec3 v = new Vec3(); v.X = num1.X * num2; v.Y = num1.Y * num2; v.Z = num1.Z * num2; return v; } #endregion }
定义OBB模型
public class OBB { public Vec3 Pos { get; set; } public Vec3 AxisX { get; set; } public Vec3 AxisY { get; set; } public Vec3 AxisZ { get; set; } public Vec3 Half_size { get; set; } }
OBB碰撞算法
public class OBBCollision { ////// check if there's a separating plane in between the selected axes //////public static bool GetSeparatingPlane( Vec3 RPos, Vec3 Plane, OBB box1, OBB box2) { return (Math.Abs(RPos* Plane) > (Math.Abs((box1.AxisX* box1.Half_size.X)*Plane) + Math.Abs((box1.AxisY* box1.Half_size.Y)*Plane) + Math.Abs((box1.AxisZ* box1.Half_size.Z)*Plane) + Math.Abs((box2.AxisX* box2.Half_size.X)*Plane) + Math.Abs((box2.AxisY* box2.Half_size.Y)*Plane) + Math.Abs((box2.AxisZ* box2.Half_size.Z)*Plane))); } ////// test for separating planes in all 15 axes ////////////public static bool GetCollision(OBB box1, OBB box2) { Vec3 RPos; RPos = box2.Pos - box1.Pos; return !(GetSeparatingPlane(RPos, box1.AxisX, box1, box2) || GetSeparatingPlane(RPos, box1.AxisY, box1, box2) || GetSeparatingPlane(RPos, box1.AxisZ, box1, box2) || GetSeparatingPlane(RPos, box2.AxisX, box1, box2) || GetSeparatingPlane(RPos, box2.AxisY, box1, box2) || GetSeparatingPlane(RPos, box2.AxisZ, box1, box2) || GetSeparatingPlane(RPos, box1.AxisX ^ box2.AxisX, box1, box2) || GetSeparatingPlane(RPos, box1.AxisX ^ box2.AxisY, box1, box2) || GetSeparatingPlane(RPos, box1.AxisX ^ box2.AxisZ, box1, box2) || GetSeparatingPlane(RPos, box1.AxisY ^ box2.AxisX, box1, box2) || GetSeparatingPlane(RPos, box1.AxisY ^ box2.AxisY, box1, box2) || GetSeparatingPlane(RPos, box1.AxisY ^ box2.AxisZ, box1, box2) || GetSeparatingPlane(RPos, box1.AxisZ ^ box2.AxisX, box1, box2) || GetSeparatingPlane(RPos, box1.AxisZ ^ box2.AxisY, box1, box2) || GetSeparatingPlane(RPos, box1.AxisZ ^ box2.AxisZ, box1, box2)); } }
测试
// create two obbs //两个OBB A和B OBB A, B; // set the first obb's properties A = new OBB(); // set its center position //定义A的中心点为(0,0,0) A.Pos = new Vec3(0, 0, 0); // set the half size //定义A的1/2边长(10,1,1),即A的边长为(20,2,2) A.Half_size = new Vec3(10, 1, 1); // set the axes orientation //定义A的x,y,z轴方向 A.AxisX = new Vec3(1, 0, 0); A.AxisY = new Vec3(0, 1, 0); A.AxisZ = new Vec3(0, 0, 1); // set the second obb's properties B = new OBB(); // set its center position B.Pos = new Vec3(20, 0, 0); // set the half size B.Half_size = new Vec3(10, 1, 1); // set the axes orientation B.AxisX = new Vec3(1, 0, 0); B.AxisY = new Vec3(0, 1, 0); B.AxisZ = new Vec3(0, 0, 1); // run the code and get the result as a message if (OBBCollision.GetCollision(A, B)) { //碰撞 Console.WriteLine("Collision!!!"); } else { //未碰撞 Console.WriteLine("No collision."); }
标签:RPos,num1,num2,C#,OBB,算法,Vec3,box1,box2 来源: https://blog.51cto.com/u_15180952/2732414