summaryrefslogtreecommitdiff
path: root/marching/Assets/Scripts
diff options
context:
space:
mode:
Diffstat (limited to 'marching/Assets/Scripts')
-rw-r--r--marching/Assets/Scripts/Physics/PhysicsManager.cs4
-rw-r--r--marching/Assets/Scripts/Physics/PhysicsManager_Collide.cs81
-rw-r--r--marching/Assets/Scripts/Physics/PhysicsManager_CollisionDetection.cs86
-rw-r--r--marching/Assets/Scripts/Physics/PhysicsQuadtree.cs18
-rw-r--r--marching/Assets/Scripts/Physics/Quadtree.cs12
-rw-r--r--marching/Assets/Scripts/TestAABB.cs32
-rw-r--r--marching/Assets/Scripts/TestAABB.cs.meta11
-rw-r--r--marching/Assets/Scripts/Utils/MathUtils.cs6
-rw-r--r--marching/Assets/Scripts/Utils/Vector2Extension.cs4
9 files changed, 237 insertions, 17 deletions
diff --git a/marching/Assets/Scripts/Physics/PhysicsManager.cs b/marching/Assets/Scripts/Physics/PhysicsManager.cs
index 164d62b..1663410 100644
--- a/marching/Assets/Scripts/Physics/PhysicsManager.cs
+++ b/marching/Assets/Scripts/Physics/PhysicsManager.cs
@@ -6,14 +6,14 @@ using UnityEngine;
public enum ColliderType
{
- Collider,
+ Collider,
Hurtbox,
Hitbox,
}
public partial class PhysicsManager : Singleton<PhysicsManager>
{
-
+ // 四叉树筛选结果
public List<IQuadTreeObject> sharedRetriveResults => m_SharedRetriveResults;
private List<IQuadTreeObject> m_SharedRetriveResults = new List<IQuadTreeObject>();
diff --git a/marching/Assets/Scripts/Physics/PhysicsManager_Collide.cs b/marching/Assets/Scripts/Physics/PhysicsManager_Collide.cs
index 7b4aa1c..4710b2e 100644
--- a/marching/Assets/Scripts/Physics/PhysicsManager_Collide.cs
+++ b/marching/Assets/Scripts/Physics/PhysicsManager_Collide.cs
@@ -3,34 +3,50 @@ using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting.Antlr3.Runtime.Tree;
using UnityEngine;
+using UnityEngine.UIElements;
+/// <summary>
+/// 物理查询
+/// </summary>
public partial class PhysicsManager : Singleton<PhysicsManager>
{
+ // 碰撞检测结果
private List<IQuadTreeObject> m_SharedCollideResults = new List<IQuadTreeObject>();
- public Vector4 GetCircleBound(Vector3 circle)
+ public static Vector4 GetCircleBound(Vector3 circle)
{
float size = circle.z * 2;
return new Vector4(circle.x, circle.y, size, size);
}
- public Vector4 GetBoxBound(Vector4 box)
+ public static Vector4 GetBoxBound(Vector4 box)
{
return box;
}
- public Vector4 GetRayBound(Vector4 line, float maxLen=20f)
+ public static Vector4 GetRayBound(Vector4 ray)
{
- Vector2 tr = line.xy() + maxLen * line.zw().normalized;
+ Vector2 tr = ray.xy() + ray.zw();
Vector4 bound = new Vector4();
- bound.x = (tr.x + line.x) / 2;
- bound.y = (tr.y + line.y) / 2;
- bound.z = Mathf.Abs(tr.x - line.x);
- bound.w = Mathf.Abs(tr.y - line.y);
+ bound.x = (tr.x + ray.x) / 2;
+ bound.y = (tr.y + ray.y) / 2;
+ bound.z = Mathf.Max(Mathf.Abs(tr.x - ray.x), 1);
+ bound.w = Mathf.Max(Mathf.Abs(tr.y - ray.y), 1);
return bound;
}
- public Vector4 GetPointBound(Vector2 point)
+ public static Vector4 GetRaySegment(Vector4 ray)
+ {
+ Vector2 tr = ray.xy() + ray.zw();
+ Vector4 seg = new Vector4();
+ seg.x = ray.x;
+ seg.y = ray.y;
+ seg.z = tr.x;
+ seg.w = tr.y;
+ return seg;
+ }
+
+ public static Vector4 GetPointBound(Vector2 point)
{
Vector4 bound = new Vector4();
bound.x = point.x;
@@ -40,6 +56,20 @@ public partial class PhysicsManager : Singleton<PhysicsManager>
return bound;
}
+ /// <summary>
+ /// 把x,y,w,h的box转换为lowerx,higherx,lowery,highery
+ /// </summary>
+ /// <returns></returns>
+ public static Vector4 GetBoxRange(Vector4 box)
+ {
+ Vector4 Range = new();
+ Range.x = box.x - box.z / 2;
+ Range.y = box.x + box.z / 2;
+ Range.z = box.y - box.w / 2;
+ Range.w = box.y + box.w / 2;
+ return Range;
+ }
+
public ref readonly List<IQuadTreeObject> CircleCast(ColliderType target, Vector3 circle)
{
m_SharedCollideResults.Clear();
@@ -109,13 +139,42 @@ public partial class PhysicsManager : Singleton<PhysicsManager>
}
/// <summary>
- /// x,y dir.x dir.y
+ /// x,y dir.x dir.y(dir带长度)
/// </summary>
/// <param name="target"></param>
/// <param name="line"></param>
/// <returns></returns>
- public ref readonly List<IQuadTreeObject> RayCast(ColliderType target, Vector4 ray, float maxLength = 20f)
+ public ref readonly List<IQuadTreeObject> RayCast(ColliderType target, Vector4 ray)
{
+ m_SharedCollideResults.Clear();
+ var retriver = GetRetriverByType(target);
+ if(retriver != null)
+ {
+ if(retriver(GetRayBound(ray)))
+ {
+ for (int i = 0; i < m_SharedRetriveResults.Count; ++i)
+ {
+ var collider = m_SharedRetriveResults[i];
+ if (collider != null)
+ {
+ if (collider is FastCircleCollider)
+ {
+ if (RayVsCircle(ray, (collider as FastCircleCollider).circle))
+ {
+ m_SharedCollideResults.Add(collider);
+ }
+ }
+ else if (collider is FastBoxCollider)
+ {
+ if (RayVsBox(ray, (collider as FastBoxCollider).box))
+ {
+ m_SharedCollideResults.Add(collider);
+ }
+ }
+ }
+ }
+ }
+ }
return ref m_SharedCollideResults;
}
diff --git a/marching/Assets/Scripts/Physics/PhysicsManager_CollisionDetection.cs b/marching/Assets/Scripts/Physics/PhysicsManager_CollisionDetection.cs
index a0dcc97..5210767 100644
--- a/marching/Assets/Scripts/Physics/PhysicsManager_CollisionDetection.cs
+++ b/marching/Assets/Scripts/Physics/PhysicsManager_CollisionDetection.cs
@@ -1,7 +1,11 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
+using static UnityEditor.Rendering.CameraUI;
+/// <summary>
+/// 碰撞检测
+/// </summary>
public partial class PhysicsManager : Singleton<PhysicsManager>
{
@@ -70,6 +74,88 @@ public partial class PhysicsManager : Singleton<PhysicsManager>
return Vector2.Dot(u, u) < radius * radius;
}
+ public static bool RayVsCircle(Vector4 ray, Vector3 circle)
+ {
+ Vector4 seg = GetRaySegment(ray);
+ Vector2 dir = ray.zw().normalized;
+ Vector2 center = circle.xy();
+ float u = Vector2.Dot(center - seg.xy(), dir);
+ Vector2 near = new Vector2();
+ if(u <= 0)
+ {
+ near = seg.xy();
+ }
+ else if(u >= ray.zw().magnitude)
+ {
+ near = seg.zw();
+ }
+ else
+ {
+ near = seg.xy() + dir * u;
+ }
+ return (near - center).sqrMagnitude <= circle.z * circle.z;
+ }
+
+
+ // From Real-time Collision Detection, p179
+ // box2d
+ public static bool RayVsBox(Vector4 ray, Vector4 box)
+ {
+ float tmin = float.MinValue;
+ float tmax = float.MaxValue;
+ Vector2 dir = ray.zw().normalized;
+ Vector4 range = GetBoxRange(box); //lowerx,higherx,lowery,highery
+ Vector2 lowerBound = new Vector2(range.x, range.z);
+ Vector2 upperBound = new Vector2(range.y, range.w);
+ //Vector2 normal = new Vector2();
+ Vector2 p = ray.xy();
+
+ for (int i = 0; i < 2; ++i)
+ {
+
+ if (dir[i] < float.Epsilon) // 和x-slab平行
+ {
+ if (p[i] < lowerBound[i] || p[i] > upperBound[i])
+ {
+ return false;
+ }
+ }
+ else
+ {
+ float inv_d = 1f / dir[i];
+ float t1 = (lowerBound[i] - p[i]) * inv_d;
+ float t2 = (upperBound[i] - p[i]) * inv_d;
+ float s = -1f;
+ if (t1 > t2)
+ {
+ MathUtils.Swap(ref t1, ref t2);
+ s = 1f;
+ }
+ if (t1 > tmin)
+ {
+ //normal = Vector2.zero;
+ //normal[i] = s;
+ tmin = t1;
+ }
+
+ tmax = Mathf.Min(tmax, t2);
+
+ if (tmin > tmax)
+ {
+ return false;
+ }
+ }
+ }
+
+ if (tmin < 0 || ray.zw().magnitude < tmin)
+ return false;
+ //// Intersection.
+ //output->fraction = tmin;
+ //output->normal = normal;
+
+ return true;
+ }
+
/// <summary>
/// box x,y,w,h circle x,y,raduis
/// </summary>
diff --git a/marching/Assets/Scripts/Physics/PhysicsQuadtree.cs b/marching/Assets/Scripts/Physics/PhysicsQuadtree.cs
index f4bad27..5cd374e 100644
--- a/marching/Assets/Scripts/Physics/PhysicsQuadtree.cs
+++ b/marching/Assets/Scripts/Physics/PhysicsQuadtree.cs
@@ -8,9 +8,20 @@ using UnityEngine;
/// </summary>
class PhysicsQuadtree
{
+ /// <summary>
+ /// 杈圭晫
+ /// </summary>
public Vector4 quadtreeRange { set { m_QuadtreeRange = value; } }
private Vector4 m_QuadtreeRange;
+
+ /// <summary>
+ /// 鏍硅妭鐐
+ /// </summary>
private Quadtree m_Quadtree;
+
+ /// <summary>
+ /// 鎵樼鐨勫叏閮ㄥ璞★紝浣嗕笉涓瀹氫細鍔犲叆鍒版爲閲岄潰锛堜腑蹇冪偣鍦ㄨ竟鐣屽鐨勪笉鍔犲叆鏍戯級
+ /// </summary>
private List<IQuadTreeObject> m_Objects = new List<IQuadTreeObject>();
public PhysicsQuadtree(Vector4 range)
@@ -33,12 +44,17 @@ class PhysicsQuadtree
{
m_Quadtree.Clear(false);
m_Quadtree.Rebound(m_QuadtreeRange);
+ InsertAllObjects();
+ }
+
+ private void InsertAllObjects()
+ {
Vector4 bound = m_Quadtree.bound;
for (int i = 0; i < m_Objects.Count; i++)
{
IQuadTreeObject obj = m_Objects[i];
// 绠鍗曠殑蹇界暐涓績鍦ㄨ竟鐣屽鐨刼bject
- if(PhysicsManager.IsPointInsideBox(bound, obj.bound.xy()))
+ if (PhysicsManager.IsPointInsideBox(bound, obj.bound.xy()))
{
m_Quadtree.Insert(obj);
}
diff --git a/marching/Assets/Scripts/Physics/Quadtree.cs b/marching/Assets/Scripts/Physics/Quadtree.cs
index 9f8ecba..a012d26 100644
--- a/marching/Assets/Scripts/Physics/Quadtree.cs
+++ b/marching/Assets/Scripts/Physics/Quadtree.cs
@@ -29,7 +29,7 @@ namespace mh
private int m_Level;
private Vector4 m_Bounds; // x,y,z,w => posx,posy,width,height
private Quadtree[] m_SubTrees; // 从右上角开始逆时针索引
- private List<IQuadTreeObject> m_Objects; // 当前层能容纳,但任何一个子树都无法容纳的对象
+ private List<IQuadTreeObject> m_Objects; // 非叶节点的为0
private bool m_IsRoot;
public Vector4 bound { get { return m_Bounds; } }
@@ -47,7 +47,6 @@ namespace mh
public bool isRoot { get { return m_IsRoot; } }
private static Queue<List<IQuadTreeObject>> m_QuadtreeObjPool = new Queue<List<IQuadTreeObject>>();
-
private static Queue<Quadtree> m_QuadtreePool = new Queue<Quadtree>();
private Quadtree QueryQuadtree(int level, Vector4 bounds)
@@ -97,8 +96,17 @@ namespace mh
m_IsRoot = isRoot;
}
+ /// <summary>
+ /// 更改边界,只适用于最外层的tree
+ /// </summary>
+ /// <param name="bounds"></param>
public void Rebound(Vector4 bounds)
{
+ if(!m_IsRoot)
+ {
+ Debug.LogError("Quadtree.Rebound()只能运用于最外层");
+ return;
+ }
m_Bounds = bounds;
}
diff --git a/marching/Assets/Scripts/TestAABB.cs b/marching/Assets/Scripts/TestAABB.cs
new file mode 100644
index 0000000..ed33ab3
--- /dev/null
+++ b/marching/Assets/Scripts/TestAABB.cs
@@ -0,0 +1,32 @@
+using System.Collections;
+using System.Collections.Generic;
+using Unity.VisualScripting;
+using UnityEngine;
+
+public class TestAABB : MonoBehaviour
+{
+
+ public Vector4 ray;
+
+ public Vector2 size;
+
+ private void Awake()
+ {
+
+ }
+
+ private void OnDrawGizmos()
+ {
+ if(PhysicsManager.RayVsBox(ray, new Vector4(transform.position.x, transform.position.y, size.x, size.y)))
+ {
+ Gizmos.color = Color.red;
+ }
+ else
+ {
+ Gizmos.color = Color.white;
+ }
+ Gizmos.DrawLine(ray.xy().ToVector3(), ray.xy().ToVector3() + ray.zw().ToVector3());
+ Gizmos.DrawCube(transform.position, size.ToVector3());
+ }
+
+}
diff --git a/marching/Assets/Scripts/TestAABB.cs.meta b/marching/Assets/Scripts/TestAABB.cs.meta
new file mode 100644
index 0000000..042e981
--- /dev/null
+++ b/marching/Assets/Scripts/TestAABB.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4ddedc9aac270da4eb59670351403718
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/marching/Assets/Scripts/Utils/MathUtils.cs b/marching/Assets/Scripts/Utils/MathUtils.cs
index a25f5e5..c997495 100644
--- a/marching/Assets/Scripts/Utils/MathUtils.cs
+++ b/marching/Assets/Scripts/Utils/MathUtils.cs
@@ -15,5 +15,11 @@ public static class MathUtils
return new Vector2(Mathf.Max(src.x, v), Mathf.Max(src.y, v));
}
+ public static void Swap(ref float f1, ref float f2)
+ {
+ float t = f1;
+ f1 = f2;
+ f2 = t;
+ }
} \ No newline at end of file
diff --git a/marching/Assets/Scripts/Utils/Vector2Extension.cs b/marching/Assets/Scripts/Utils/Vector2Extension.cs
index 2fcaf60..aa96509 100644
--- a/marching/Assets/Scripts/Utils/Vector2Extension.cs
+++ b/marching/Assets/Scripts/Utils/Vector2Extension.cs
@@ -1,5 +1,6 @@
using System.Collections;
using System.Collections.Generic;
+using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;
@@ -17,6 +18,7 @@ public static class Vector2Extension
public static Vector3 ToVector3(this Vector2 src)
{
- return ConvertToVector3( src);
+ return ConvertToVector3(src);
}
+
}