mirror of
https://github.com/BlackMATov/unity-iso-tools.git
synced 2025-12-16 22:16:55 +07:00
quad tree for visibility wip
This commit is contained in:
@@ -7,12 +7,60 @@ using UnityEngine.Profiling;
|
||||
|
||||
namespace IsoTools.Internal {
|
||||
public class IsoScreenSolver {
|
||||
Vector2 _minIsoXY = Vector2.zero;
|
||||
IsoAssocList<IsoObject> _curVisibles = new IsoAssocList<IsoObject>();
|
||||
IsoAssocList<IsoObject> _oldVisibles = new IsoAssocList<IsoObject>();
|
||||
IsoGrid<IsoObject> _visibleGrid = new IsoGrid<IsoObject>(new IsoGridItemAdapter(), 47);
|
||||
IsoGridLookUpper _gridLookUpper = new IsoGridLookUpper();
|
||||
List<Renderer> _tmpRenderers = new List<Renderer>();
|
||||
Vector2 _minIsoXY = Vector2.zero;
|
||||
IsoAssocList<IsoObject> _oldVisibles = new IsoAssocList<IsoObject>();
|
||||
IsoAssocList<IsoObject> _curVisibles = new IsoAssocList<IsoObject>();
|
||||
|
||||
IsoQuadTree<IsoObject> _quadTree = new IsoQuadTree<IsoObject>(47);
|
||||
IsoGrid<IsoObject> _screenGrid = new IsoGrid<IsoObject>(new IsoGridItemAdapter(), 47);
|
||||
|
||||
IsoQTBoundsLookUpper _qtBoundsLU = new IsoQTBoundsLookUpper();
|
||||
IsoQTContentLookUpper _qtContentLU = new IsoQTContentLookUpper();
|
||||
IsoGridLookUpper _screenGridLU = new IsoGridLookUpper();
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// IsoQTBoundsLookUpper
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
class IsoQTBoundsLookUpper : IsoQuadTree<IsoObject>.IBoundsLookUpper {
|
||||
public void LookUp(IsoRect bounds) {
|
||||
#if UNITY_EDITOR
|
||||
IsoUtils.DrawRect(bounds, Color.blue);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// IsoQTContentLookUpper
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
class IsoQTContentLookUpper : IsoQuadTree<IsoObject>.IContentLookUpper {
|
||||
Camera[] _tmpCameras = new Camera[8];
|
||||
IsoScreenSolver _screenSolver = null;
|
||||
|
||||
public void LookUp(IsoObject iso_object) {
|
||||
iso_object.Internal.Placed = false;
|
||||
_screenSolver._oldVisibles.Add(iso_object);
|
||||
}
|
||||
|
||||
public void LookUpForVisibility(IsoScreenSolver screen_solver) {
|
||||
_screenSolver = screen_solver;
|
||||
var cam_count = Camera.GetAllCameras(_tmpCameras);
|
||||
for ( var i = 0; i < cam_count; ++i ) {
|
||||
var camera = _tmpCameras[i];
|
||||
var vp_rect = camera.rect;
|
||||
var wrl_min = camera.ViewportToWorldPoint(new Vector3(vp_rect.xMin, vp_rect.yMin));
|
||||
var wrl_max = camera.ViewportToWorldPoint(new Vector3(vp_rect.xMax, vp_rect.yMax));
|
||||
_screenSolver._quadTree.VisitItemsByBounds(new IsoRect(wrl_min, wrl_max), this);
|
||||
}
|
||||
_screenSolver = null;
|
||||
System.Array.Clear(_tmpCameras, 0, _tmpCameras.Length);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
@@ -46,15 +94,18 @@ namespace IsoTools.Internal {
|
||||
IsoObject _isoObject;
|
||||
|
||||
public void LookUp(IsoList<IsoObject> items) {
|
||||
LookUpSectorDepends(_isoObject, items);
|
||||
LookUpSectorRDepends(_isoObject, items);
|
||||
LookUpCellForLDepends(_isoObject, items);
|
||||
LookUpCellForRDepends(_isoObject, items);
|
||||
}
|
||||
|
||||
public void Setup(IsoObject iso_object) {
|
||||
public void LookUpForDepends(
|
||||
IsoScreenSolver screen_solver, IsoObject iso_object)
|
||||
{
|
||||
_isoObject = iso_object;
|
||||
}
|
||||
|
||||
public void Reset() {
|
||||
screen_solver._screenGrid.LookUpCells(
|
||||
iso_object.Internal.MinGridCell,
|
||||
iso_object.Internal.MaxGridCell,
|
||||
this);
|
||||
_isoObject = null;
|
||||
}
|
||||
}
|
||||
@@ -69,14 +120,14 @@ namespace IsoTools.Internal {
|
||||
get { return _minIsoXY; }
|
||||
}
|
||||
|
||||
public IsoAssocList<IsoObject> curVisibles {
|
||||
get { return _curVisibles; }
|
||||
}
|
||||
|
||||
public IsoAssocList<IsoObject> oldVisibles {
|
||||
get { return _oldVisibles; }
|
||||
}
|
||||
|
||||
public IsoAssocList<IsoObject> curVisibles {
|
||||
get { return _curVisibles; }
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Callbacks
|
||||
@@ -84,15 +135,22 @@ namespace IsoTools.Internal {
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
public void OnAddInstance(IsoObject iso_object) {
|
||||
_quadTree.AddItem(
|
||||
iso_object.Internal.ScreenBounds,
|
||||
iso_object);
|
||||
}
|
||||
|
||||
public void OnRemoveInstance(IsoObject iso_object) {
|
||||
_oldVisibles.Remove(iso_object);
|
||||
_curVisibles.Remove(iso_object);
|
||||
_quadTree.RemoveItem(iso_object);
|
||||
ClearIsoObjectDepends(iso_object);
|
||||
}
|
||||
|
||||
public bool OnMarkDirtyInstance(IsoObject iso_object) {
|
||||
_quadTree.MoveItem(
|
||||
iso_object.Internal.ScreenBounds,
|
||||
iso_object);
|
||||
if ( !iso_object.Internal.Dirty && _curVisibles.Contains(iso_object) ) {
|
||||
iso_object.Internal.Dirty = true;
|
||||
return true;
|
||||
@@ -102,6 +160,7 @@ namespace IsoTools.Internal {
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public void OnDrawGizmos(IsoWorld iso_world) {
|
||||
_quadTree.VisitAllBounds(_qtBoundsLU);
|
||||
/*
|
||||
for ( int y = 0, ye = (int)_sectorsNumPosCount.y; y < ye; ++y ) {
|
||||
for ( int x = 0, xe = (int)_sectorsNumPosCount.x; x < xe; ++x ) {
|
||||
@@ -126,32 +185,27 @@ namespace IsoTools.Internal {
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
public void StepSortingAction(IsoWorld iso_world, IsoAssocList<IsoObject> instances) {
|
||||
Profiler.BeginSample("ResolveVisibles");
|
||||
Profiler.BeginSample("IsoScreenSolver.ResolveVisibles");
|
||||
ResolveVisibles(instances);
|
||||
Profiler.EndSample();
|
||||
Profiler.BeginSample("ResolveVisibleGrid");
|
||||
Profiler.BeginSample("IsoScreenSolver.ResolveVisibleGrid");
|
||||
ResolveVisibleGrid(iso_world);
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
public void PostStepSortingAction() {
|
||||
_tmpRenderers.Clear();
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
_curVisibles.Clear();
|
||||
_oldVisibles.Clear();
|
||||
_visibleGrid.ClearGrid();
|
||||
_curVisibles.Clear();
|
||||
_quadTree.Clear();
|
||||
_screenGrid.ClearGrid();
|
||||
}
|
||||
|
||||
public void SetupIsoObjectDepends(IsoObject iso_object) {
|
||||
ClearIsoObjectDepends(iso_object);
|
||||
_gridLookUpper.Setup(iso_object);
|
||||
_visibleGrid.LookUpCells(
|
||||
iso_object.Internal.MinGridCell,
|
||||
iso_object.Internal.MaxGridCell,
|
||||
_gridLookUpper);
|
||||
_gridLookUpper.Reset();
|
||||
_screenGridLU.LookUpForDepends(this, iso_object);
|
||||
}
|
||||
|
||||
public void ClearIsoObjectDepends(IsoObject iso_object) {
|
||||
@@ -173,7 +227,15 @@ namespace IsoTools.Internal {
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
void ResolveVisibles(IsoAssocList<IsoObject> instances) {
|
||||
_oldVisibles.Clear();
|
||||
Profiler.BeginSample("ProcessAllInstances");
|
||||
ProcessAllInstances(instances);
|
||||
Profiler.EndSample();
|
||||
Profiler.BeginSample("ProcessNewVisibles");
|
||||
ProcessNewVisibles();
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
void ProcessAllInstances(IsoAssocList<IsoObject> instances) {
|
||||
if ( instances.Count > 0 ) {
|
||||
_minIsoXY.Set(float.MaxValue, float.MaxValue);
|
||||
for ( int i = 0, e = instances.Count; i < e; ++i ) {
|
||||
@@ -191,36 +253,22 @@ namespace IsoTools.Internal {
|
||||
{
|
||||
iso_object.FixIsoPosition();
|
||||
}
|
||||
if ( IsIsoObjectVisible(iso_object) ) {
|
||||
iso_object.Internal.Placed = false;
|
||||
_oldVisibles.Add(iso_object);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_minIsoXY.Set(0.0f, 0.0f);
|
||||
}
|
||||
var temp_visibles = _curVisibles;
|
||||
}
|
||||
|
||||
void ProcessNewVisibles() {
|
||||
_oldVisibles.Clear();
|
||||
_qtContentLU.LookUpForVisibility(this);
|
||||
SwapCurrentVisibles();
|
||||
}
|
||||
|
||||
void SwapCurrentVisibles() {
|
||||
var swap_tmp = _curVisibles;
|
||||
_curVisibles = _oldVisibles;
|
||||
_oldVisibles = temp_visibles;
|
||||
}
|
||||
|
||||
bool IsIsoObjectVisible(IsoObject iso_object) {
|
||||
var renderers = GetIsoObjectRenderers(iso_object);
|
||||
for ( int i = 0, e = renderers.Count; i < e; ++i ) {
|
||||
if ( renderers[i].isVisible ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Renderer> GetIsoObjectRenderers(IsoObject iso_object) {
|
||||
if ( iso_object.cacheRenderers ) {
|
||||
return iso_object.Internal.Renderers;
|
||||
} else {
|
||||
iso_object.GetComponentsInChildren<Renderer>(_tmpRenderers);
|
||||
return _tmpRenderers;
|
||||
}
|
||||
_oldVisibles = swap_tmp;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
@@ -230,24 +278,24 @@ namespace IsoTools.Internal {
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
void ResolveVisibleGrid(IsoWorld iso_world) {
|
||||
_visibleGrid.ClearItems();
|
||||
_screenGrid.ClearItems();
|
||||
for ( int i = 0, e = _curVisibles.Count; i < e; ++i ) {
|
||||
var iso_object = _curVisibles[i];
|
||||
_visibleGrid.AddItem(iso_object);
|
||||
_screenGrid.AddItem(iso_object);
|
||||
}
|
||||
var min_sector_size = IsoUtils.Vec2MaxF(
|
||||
iso_world.IsoToScreen(IsoUtils.vec3OneXY) -
|
||||
iso_world.IsoToScreen(Vector3.zero));
|
||||
_visibleGrid.RebuildGrid(min_sector_size);
|
||||
_screenGrid.RebuildGrid(min_sector_size);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// LookUpSectorDepends
|
||||
// LookUpCellForDepends
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
static void LookUpSectorDepends(IsoObject obj_a, IsoList<IsoObject> others) {
|
||||
static void LookUpCellForLDepends(IsoObject obj_a, IsoList<IsoObject> others) {
|
||||
for ( int i = 0, e = others.Count; i < e; ++i ) {
|
||||
var obj_b = others[i];
|
||||
if ( obj_a != obj_b && !obj_b.Internal.Dirty && IsIsoObjectDepends(obj_a, obj_b) ) {
|
||||
@@ -257,7 +305,7 @@ namespace IsoTools.Internal {
|
||||
}
|
||||
}
|
||||
|
||||
static void LookUpSectorRDepends(IsoObject obj_a, IsoList<IsoObject> others) {
|
||||
static void LookUpCellForRDepends(IsoObject obj_a, IsoList<IsoObject> others) {
|
||||
for ( int i = 0, e = others.Count; i < e; ++i ) {
|
||||
var obj_b = others[i];
|
||||
if ( obj_a != obj_b && !obj_b.Internal.Dirty && IsIsoObjectDepends(obj_b, obj_a) ) {
|
||||
@@ -293,9 +341,13 @@ namespace IsoTools.Internal {
|
||||
var dB_y = b_max.y - a_min.y;
|
||||
var dB_z = a_max.z - b_min.z;
|
||||
|
||||
var dP_x = a_size.x + b_size.x - Mathf.Abs(dA_x - dB_x);
|
||||
var dP_y = a_size.y + b_size.y - Mathf.Abs(dA_y - dB_y);
|
||||
var dP_z = a_size.z + b_size.z - Mathf.Abs(dA_z - dB_z);
|
||||
var dD_x = dB_x - dA_x;
|
||||
var dD_y = dB_y - dA_y;
|
||||
var dD_z = dB_z - dA_z;
|
||||
|
||||
var dP_x = a_size.x + b_size.x - (dD_x > 0.0f ? dD_x : -dD_x);
|
||||
var dP_y = a_size.y + b_size.y - (dD_y > 0.0f ? dD_y : -dD_y);
|
||||
var dP_z = a_size.z + b_size.z - (dD_z > 0.0f ? dD_z : -dD_z);
|
||||
|
||||
if ( dP_x <= dP_y && dP_x <= dP_z ) {
|
||||
return dA_x > dB_x;
|
||||
|
||||
Reference in New Issue
Block a user