zoukankan      html  css  js  c++  java
  • C#实现OBB碰撞算法

    原理在这里
    代码翻写自Simple Oriented Bounding Box OBB collision detection explaining的高赞答案(C++)

    向量类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
    {
        /// <summary>
        /// check if there's a separating plane in between the selected axes
        /// </summary>
        /// <returns></returns>
        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)));
        }
    
        /// <summary>
        /// test for separating planes in all 15 axes
        /// </summary>
        /// <param name="box1"></param>
        /// <param name="box2"></param>
        /// <returns></returns>
        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.");
    }
    
  • 相关阅读:
    习题4
    习题5
    习题9(函数)
    习题6
    习题8
    IIS7站点/虚拟目录中访问共享文件夹(转)
    oracle将于九月或十月发布.net纯托管代码ODP.NET beta版
    Application Request Routing (ARR) TIME OUT 502
    asp.net mvc 性能测试工具 Glimpse
    2013.04.23 总结
  • 原文地址:https://www.cnblogs.com/Lulus/p/13914215.html
Copyright © 2011-2022 走看看