Skip to content

Commit

Permalink
Fix Collisions
Browse files Browse the repository at this point in the history
  • Loading branch information
james7132 committed Feb 25, 2018
1 parent a156b9c commit 7a9a3b3
Show file tree
Hide file tree
Showing 24 changed files with 385 additions and 125 deletions.
6 changes: 3 additions & 3 deletions Assets/DanmakU/Runtime/Bounds2D.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ public void Expand(Vector2 amount) {
/// <returns>true if there is an intersection between bounds, false otherwise.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Intersects(Bounds2D bounds) {
return (Math.Abs(Center.x - bounds.Center.x) * 2 < Extents.x + bounds.Extents.x) &&
(Math.Abs(Center.y - bounds.Center.y) * 2 < Extents.y + bounds.Extents.y);
return (Math.Abs(Center.x - bounds.Center.x) < Extents.x + bounds.Size.x) &&
(Math.Abs(Center.y - bounds.Center.y) < Extents.y + bounds.Extents.y);
}

/// <summary>
Expand All @@ -129,7 +129,7 @@ public bool Contains(Vector2 point) {
}

public static implicit operator Bounds2D(Bounds bounds) {
return new Bounds2D(bounds.center, bounds.extents);
return new Bounds2D(bounds.center, bounds.size);
}

public static implicit operator Bounds(Bounds2D bounds) {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions Assets/DanmakU/Runtime/Colliders/DestroyDanmakuCollider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace DanmakU {

public class DestroyDanmakuCollider : MonoBehaviour {

public DanmakuCollider Collider;

/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
void OnEnable() {
if (Collider != null) {
Debug.Log("Subscribed");
Collider.OnDanmakuCollision += OnDanmakuCollision;
}
}

/// <summary>
/// This function is called when the behaviour becomes disabled or inactive.
/// </summary>
void OnDisable() {
if (Collider != null) {
Collider.OnDanmakuCollision -= OnDanmakuCollision;
}
}

void OnDanmakuCollision(DanmakuCollisionList collisions) {
foreach (var collision in collisions) {
collision.Danmaku.Destroy();
}
}

/// <summary>
/// Reset is called when the user hits the Reset button in the Inspector's
/// context menu or when adding the component the first time.
/// </summary>
void Reset() {
Collider = GetComponent<DanmakuCollider>();
}

}

}
11 changes: 11 additions & 0 deletions Assets/DanmakU/Runtime/Colliders/DestroyDanmakuCollider.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Assets/DanmakU/Runtime/Core/Collisions.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Assertions;
using Unity.Collections.LowLevel.Unsafe;

namespace DanmakU {

Expand All @@ -15,14 +15,17 @@ struct ColliderData {
public int LayerMask;
}

static RaycastHit2D[] raycastCache = new RaycastHit2D[256];
static readonly List<DanmakuCollider> Colliders;
static readonly MultiMap<Collider2D, DanmakuCollider> ColliderMap;
static readonly List<Bounds2D>[] Data;
static Bounds2D GlobalBounds;
static int GlobalLayerMask;
static int HighestLayer;

static DanmakuCollider() {
Colliders = new List<DanmakuCollider>();
ColliderMap = new MultiMap<Collider2D, DanmakuCollider>();
Data = new List<Bounds2D>[sizeof(int) * 8];
for (var i = 0; i < Data.Length; i++) {
Data[i] = new List<Bounds2D>();
Expand Down Expand Up @@ -54,15 +57,31 @@ internal static void RebuildSpatialHashes() {
}
}

MutableDanmakuCollisionList collidedDanmaku;
Collider2D[] colliders;
ColliderData data;

public event Action<DanmakuCollisionList> OnDanmakuCollision;

/// <summary>
/// Awake is called when the script instance is being loaded.
/// </summary>
void Awake() {
colliders = GetComponents<Collider2D>();
data = BuildData();
collidedDanmaku = new MutableDanmakuCollisionList();
foreach (var collider in colliders) {
ColliderMap.Add(collider, this);
}
}

/// <summary>
/// This function is called when the MonoBehaviour will be destroyed.
/// </summary>
void OnDestroy() {
foreach (var collider in colliders) {
ColliderMap.RemoveElement(collider, this);
}
}

/// <summary>
Expand All @@ -82,6 +101,49 @@ void FixedUpdate() {
data = BuildData();
}

internal static unsafe void TestPoolCollisions(DanmakuPool pool) {
var layersPtr = (int*)(pool.CollisionMasks.GetUnsafePtr());
var count = pool.ActiveCount;
for (var i = 0; i < count; i++) {
if (*layersPtr++ == 0) continue;
var layerMask = pool.CollisionMasks[i];
var oldPosition = pool.OldPositions[i];
var direction = pool.Positions[i] - oldPosition;
var distance = direction.magnitude;
var hits = Physics2D.CircleCastNonAlloc(oldPosition, pool.ColliderRadius, direction, raycastCache, distance, layerMask);
if (hits <= 0) continue;
var danmaku = new Danmaku(pool, i);
for (var j = 0; j < hits; j++) {
var collider = raycastCache[j].collider;
List<DanmakuCollider> danmakuColliders;
if (!ColliderMap.TryGetValue(collider, out danmakuColliders)) continue;
var collision = new DanmakuCollision {
Danmaku = danmaku,
RaycastHit = raycastCache[j]
};
foreach (var dCollider in danmakuColliders) {
if (dCollider != null && dCollider.isActiveAndEnabled) {
dCollider.AddDanmaku(collision);
}
}
}
}
}

internal static void FlushAll() {
foreach (var collider in Colliders) {
collider.Flush();
}
}

internal void AddDanmaku(DanmakuCollision danmaku) => collidedDanmaku.Add(danmaku);
internal void Flush() {
if (collidedDanmaku.Count > 0 && OnDanmakuCollision != null) {
OnDanmakuCollision(collidedDanmaku.AsReadOnly());
}
collidedDanmaku.Clear();
}

internal static int TestCollisions(Bounds2D bounds) {
if (!GlobalBounds.Intersects(bounds)) return 0;
int collisions = 0;
Expand Down
12 changes: 12 additions & 0 deletions Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollision.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace DanmakU {

public struct DanmakuCollision {
public Danmaku Danmaku;
public RaycastHit2D RaycastHit;
}

}
11 changes: 11 additions & 0 deletions Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollision.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 60 additions & 0 deletions Assets/DanmakU/Runtime/Core/Collisions/DanmakuCollisionList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Collections.LowLevel.Unsafe;

namespace DanmakU {

/// <summary>
/// A read-only list of Danmaku.
/// </summary>
public struct DanmakuCollisionList : IReadOnlyList<DanmakuCollision> {

readonly DanmakuCollision[] Array;
public int Count { get; }

internal DanmakuCollisionList(DanmakuCollision[] array, int count) {
Array = array;
Count = count;
}

public DanmakuCollision this[int index] {
get {
if (index < 0 && index >= Count) {
throw new IndexOutOfRangeException(nameof(index));
}
return Array[index];
}
}

public Enumerator GetEnumerator() => new Enumerator(this);
IEnumerator<DanmakuCollision> IEnumerable<DanmakuCollision>.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

public struct Enumerator : IEnumerator<DanmakuCollision> {

readonly DanmakuCollisionList list;
int currentIndex;
public DanmakuCollision Current => list[currentIndex];
object IEnumerator.Current => Current;

internal Enumerator(DanmakuCollisionList list) {
this.list = list;
currentIndex = -1;
}

public bool MoveNext() {
currentIndex++;
return currentIndex < list.Count;
}

public void Reset() => currentIndex = -1;

public void Dispose() {}

}

}

}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Collections.LowLevel.Unsafe;

namespace DanmakU {

internal class MutableDanmakuCollisionList {

const int kDefaultCapacity = 16;
const int kGrowthFactor = 2;

DanmakuCollision[] Array;
public int Capacity => Array?.Length ?? kDefaultCapacity;
public int Count { get; private set; }

public DanmakuCollisionList AsReadOnly() => new DanmakuCollisionList(Array, Count);

public MutableDanmakuCollisionList() {
Array = new DanmakuCollision[kDefaultCapacity];
}

public void Add(DanmakuCollision obj) {
if (Contains(obj)) return;
CheckCapacity(1);
Array[Count++] = obj;
}

public bool Contains(DanmakuCollision obj) {
if (Count <= 1024) {
bool contained = false;
for (var i = 0; i < Count; i++) {
contained |= Array[i].Danmaku == obj.Danmaku;
}
return contained;
} else {
for (var i = 0; i < Count; i++) {
if (Array[i].Danmaku== obj.Danmaku) return true;
}
return false;
}
}

public void Clear() => Count = 0;

void CheckCapacity(int count) {
if (Count + count <= Capacity) return;
var newArray = new DanmakuCollision[Capacity * kGrowthFactor];
System.Array.Copy(Array, 0, newArray, 0, Count);
Array = newArray;
}

}

}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 7a9a3b3

Please sign in to comment.