fix isogrid float problems

This commit is contained in:
2016-12-24 17:50:44 +07:00
parent 486c95f9cd
commit a7f4fee821
4 changed files with 89 additions and 81 deletions

View File

@@ -260,7 +260,7 @@ Prefab:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 417424, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2} - target: {fileID: 417424, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2}
propertyPath: m_LocalPosition.z propertyPath: m_LocalPosition.z
value: 1.2 value: 1.1
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 417424, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2} - target: {fileID: 417424, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2}
propertyPath: m_LocalRotation.x propertyPath: m_LocalRotation.x
@@ -366,7 +366,7 @@ Prefab:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 11472392, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2} - target: {fileID: 11472392, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2}
propertyPath: _position.x propertyPath: _position.x
value: 0 value: -0.000000022758144
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 11472392, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2} - target: {fileID: 11472392, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2}
propertyPath: _position.y propertyPath: _position.y
@@ -424,7 +424,7 @@ Prefab:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 417424, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2} - target: {fileID: 417424, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2}
propertyPath: m_LocalPosition.z propertyPath: m_LocalPosition.z
value: 1.3000001 value: 1.2
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 417424, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2} - target: {fileID: 417424, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2}
propertyPath: m_LocalRotation.x propertyPath: m_LocalRotation.x
@@ -675,7 +675,7 @@ Prefab:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 417424, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2} - target: {fileID: 417424, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2}
propertyPath: m_LocalPosition.z propertyPath: m_LocalPosition.z
value: 1.1 value: 1.3000001
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 417424, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2} - target: {fileID: 417424, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2}
propertyPath: m_LocalRotation.x propertyPath: m_LocalRotation.x
@@ -785,7 +785,7 @@ Prefab:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 11472392, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2} - target: {fileID: 11472392, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2}
propertyPath: _position.y propertyPath: _position.y
value: 0 value: 0.000000022758137
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 11472392, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2} - target: {fileID: 11472392, guid: 185575a05f87743c0b2ddb83dd39c6cd, type: 2}
propertyPath: _position.z propertyPath: _position.z

View File

@@ -1,21 +1,18 @@
using UnityEngine; using UnityEngine;
using System.Collections.Generic;
namespace IsoTools.Internal { namespace IsoTools.Internal {
public class IsoGrid<T> { public class IsoGrid<T> {
// ---------------------------------------------------------------------
// //
// Cell // CellPool
// //
// ---------------------------------------------------------------------
class Cell { class Cell {
public IsoList<T> Items = new IsoList<T>(); public IsoList<T> Items = new IsoList<T>();
} }
//
// CellPool
//
class CellPool : IsoPool<Cell> { class CellPool : IsoPool<Cell> {
public CellPool(int capacity) : base(capacity) { public CellPool(int capacity) : base(capacity) {
} }
@@ -29,27 +26,27 @@ namespace IsoTools.Internal {
} }
} }
// ---------------------------------------------------------------------
// //
// IItemAdapter // Interfaces
// //
// ---------------------------------------------------------------------
public interface IItemAdapter { public interface IItemAdapter {
IsoRect GetBounds (T item); IsoRect GetBounds (T item);
void SetMinMaxCells (T item, Vector2 min, Vector2 max); void SetMinMaxCells (T item, IsoPoint2 min, IsoPoint2 max);
void GetMinMaxCells (T item, ref Vector2 min, ref Vector2 max); void GetMinMaxCells (T item, ref IsoPoint2 min, ref IsoPoint2 max);
} }
//
// ILookUpper
//
public interface ILookUpper { public interface ILookUpper {
void LookUp(IsoList<T> items); void LookUp(IsoList<T> items);
} }
// ---------------------------------------------------------------------
// //
// Members // Members
// //
// ---------------------------------------------------------------------
IsoIPool<Cell> _cellPool = null; IsoIPool<Cell> _cellPool = null;
IsoList<Cell> _gridCells = null; IsoList<Cell> _gridCells = null;
@@ -58,13 +55,15 @@ namespace IsoTools.Internal {
IItemAdapter _itemAdapter = null; IItemAdapter _itemAdapter = null;
float _gridCellSize = 0.0f; float _gridCellSize = 0.0f;
Vector2 _gridMinNumPos = Vector2.zero; IsoPoint2 _gridMinNumPos = IsoPoint2.zero;
Vector2 _gridMaxNumPos = Vector2.zero; IsoPoint2 _gridMaxNumPos = IsoPoint2.zero;
Vector2 _gridNumPosCount = Vector2.zero; IsoPoint2 _gridNumPosCount = IsoPoint2.zero;
// ---------------------------------------------------------------------
// //
// Public // Public
// //
// ---------------------------------------------------------------------
public IsoGrid(IItemAdapter item_adapter, int capacity) { public IsoGrid(IItemAdapter item_adapter, int capacity) {
if ( item_adapter == null ) { if ( item_adapter == null ) {
@@ -89,6 +88,10 @@ namespace IsoTools.Internal {
} }
public void RebuildGrid(float min_cell_size) { public void RebuildGrid(float min_cell_size) {
if ( min_cell_size < Mathf.Epsilon ) {
throw new System.ArgumentOutOfRangeException(
"min_cell_size", "min_cell_size must be >= Mathf.Epsilon");
}
ClearGrid(); ClearGrid();
CalculateCellSize(min_cell_size); CalculateCellSize(min_cell_size);
PrepareGridNumPos(); PrepareGridNumPos();
@@ -101,24 +104,37 @@ namespace IsoTools.Internal {
_cellPool.Release(_gridCells.Pop()); _cellPool.Release(_gridCells.Pop());
} }
_gridCellSize = 0.0f; _gridCellSize = 0.0f;
_gridMinNumPos = Vector2.zero; _gridMinNumPos = IsoPoint2.zero;
_gridMaxNumPos = Vector2.zero; _gridMaxNumPos = IsoPoint2.zero;
_gridNumPosCount = Vector2.zero; _gridNumPosCount = IsoPoint2.zero;
} }
public void LookUpCells(Vector2 min, Vector2 max, ILookUpper look_upper) { public void LookUpCells(
for ( var y = min.y; y < max.y; ++y ) { IsoPoint2 min_cell, IsoPoint2 max_cell, ILookUpper look_upper)
for ( var x = min.x; x < max.x; ++x ) { {
var cell = FindCell(x, y); if ( min_cell.x < 0 || min_cell.y < 0 ) {
if ( cell != null ) { throw new System.ArgumentOutOfRangeException("min_cell");
}
if ( min_cell.y >= _gridNumPosCount.x || min_cell.y >= _gridNumPosCount.y ) {
throw new System.ArgumentOutOfRangeException("max_cell");
}
if ( look_upper == null ) {
throw new System.ArgumentNullException("look_upper");
}
for ( int y = min_cell.y, ye = max_cell.y; y < ye; ++y ) {
for ( int x = min_cell.x, xe = max_cell.x; x < xe; ++x ) {
var cell = GetCell(x, y);
if ( cell.Items.Count > 0 ) {
look_upper.LookUp(cell.Items); look_upper.LookUp(cell.Items);
} }
}} }}
} }
// ---------------------------------------------------------------------
// //
// Private // Private
// //
// ---------------------------------------------------------------------
void CalculateCellSize(float min_cell_size) { void CalculateCellSize(float min_cell_size) {
_gridCellSize = 0.0f; _gridCellSize = 0.0f;
@@ -129,51 +145,51 @@ namespace IsoTools.Internal {
_gridCellSize += size_x > size_y ? size_x : size_y; _gridCellSize += size_x > size_y ? size_x : size_y;
} }
_gridCellSize = _gridItems.Count > 0 _gridCellSize = _gridItems.Count > 0
? Mathf.Round(Mathf.Max(min_cell_size, _gridCellSize / _gridItems.Count)) ? Mathf.Max(min_cell_size, _gridCellSize / _gridItems.Count)
: min_cell_size; : min_cell_size;
} }
void PrepareGridNumPos() { void PrepareGridNumPos() {
if ( _gridItems.Count > 0 ) { if ( _gridItems.Count > 0 ) {
_gridMinNumPos.Set(float.MaxValue, float.MaxValue); _gridMinNumPos.Set(int.MaxValue, int.MaxValue);
_gridMaxNumPos.Set(float.MinValue, float.MinValue); _gridMaxNumPos.Set(int.MinValue, int.MinValue);
for ( int i = 0, e = _gridItems.Count; i < e; ++i ) { for ( int i = 0, e = _gridItems.Count; i < e; ++i ) {
var item = _gridItems[i]; var item = _gridItems[i];
var bounds = _itemAdapter.GetBounds(item); var bounds = _itemAdapter.GetBounds(item);
var min_x = bounds.x.min / _gridCellSize; var min_f_x = bounds.x.min / _gridCellSize;
var min_y = bounds.y.min / _gridCellSize; var min_f_y = bounds.y.min / _gridCellSize;
var max_x = bounds.x.max / _gridCellSize; var max_f_x = bounds.x.max / _gridCellSize;
var max_y = bounds.y.max / _gridCellSize; var max_f_y = bounds.y.max / _gridCellSize;
var min_cell_x = (float)(int)(min_x >= 0.0f ? min_x : min_x - 1.0f); var min_i_x = (int)(min_f_x >= 0.0f ? min_f_x : min_f_x - 1.0f);
var min_cell_y = (float)(int)(min_y >= 0.0f ? min_y : min_y - 1.0f); var min_i_y = (int)(min_f_y >= 0.0f ? min_f_y : min_f_y - 1.0f);
var max_cell_x = (float)(int)(max_x >= 0.0f ? max_x + 1.0f : max_x); var max_i_x = (int)(max_f_x >= 0.0f ? max_f_x + 1.0f : max_f_x);
var max_cell_y = (float)(int)(max_y >= 0.0f ? max_y + 1.0f : max_y); var max_i_y = (int)(max_f_y >= 0.0f ? max_f_y + 1.0f : max_f_y);
if ( _gridMinNumPos.x > min_cell_x ) { if ( _gridMinNumPos.x > min_i_x ) {
_gridMinNumPos.x = min_cell_x; _gridMinNumPos.x = min_i_x;
} }
if ( _gridMinNumPos.y > min_cell_y ) { if ( _gridMinNumPos.y > min_i_y ) {
_gridMinNumPos.y = min_cell_y; _gridMinNumPos.y = min_i_y;
} }
if ( _gridMaxNumPos.x < max_cell_x ) { if ( _gridMaxNumPos.x < max_i_x ) {
_gridMaxNumPos.x = max_cell_x; _gridMaxNumPos.x = max_i_x;
} }
if ( _gridMaxNumPos.y < max_cell_y ) { if ( _gridMaxNumPos.y < max_i_y ) {
_gridMaxNumPos.y = max_cell_y; _gridMaxNumPos.y = max_i_y;
} }
_itemAdapter.SetMinMaxCells( _itemAdapter.SetMinMaxCells(
item, item,
new Vector2(min_cell_x, min_cell_y), new IsoPoint2(min_i_x, min_i_y),
new Vector2(max_cell_x, max_cell_y)); new IsoPoint2(max_i_x, max_i_y));
} }
} else { } else {
_gridMinNumPos.Set(0.0f, 0.0f); _gridMinNumPos.Set(0, 0);
_gridMaxNumPos.Set(_gridCellSize, _gridCellSize); _gridMaxNumPos.Set(1, 1);
} }
_gridNumPosCount = _gridMaxNumPos - _gridMinNumPos; _gridNumPosCount = _gridMaxNumPos - _gridMinNumPos;
} }
void SetupGridCells() { void SetupGridCells() {
var cell_count = Mathf.RoundToInt(_gridNumPosCount.x * _gridNumPosCount.y); var cell_count = _gridNumPosCount.x * _gridNumPosCount.y;
if ( _gridCells.Capacity < cell_count ) { if ( _gridCells.Capacity < cell_count ) {
_gridCells.Capacity = cell_count * 2; _gridCells.Capacity = cell_count * 2;
} }
@@ -183,32 +199,24 @@ namespace IsoTools.Internal {
} }
void FillGridCells() { void FillGridCells() {
var min_cell = Vector2.zero; var min_cell = IsoPoint2.zero;
var max_cell = Vector2.zero; var max_cell = IsoPoint2.zero;
for ( int i = 0, e = _gridItems.Count; i < e; ++i ) { for ( int i = 0, e = _gridItems.Count; i < e; ++i ) {
var item = _gridItems[i]; var item = _gridItems[i];
_itemAdapter.GetMinMaxCells(item, ref min_cell, ref max_cell); _itemAdapter.GetMinMaxCells(item, ref min_cell, ref max_cell);
min_cell -= _gridMinNumPos; min_cell -= _gridMinNumPos;
max_cell -= _gridMinNumPos; max_cell -= _gridMinNumPos;
_itemAdapter.SetMinMaxCells(item, min_cell, max_cell); _itemAdapter.SetMinMaxCells(item, min_cell, max_cell);
for ( var y = min_cell.y; y < max_cell.y; ++y ) { for ( int y = min_cell.y, ye = max_cell.y; y < ye; ++y ) {
for ( var x = min_cell.x; x < max_cell.x; ++x ) { for ( int x = min_cell.x, xe = max_cell.x; x < xe; ++x ) {
var cell = FindCell(x, y); var cell = GetCell(x, y);
if ( cell != null ) {
cell.Items.Add(item); cell.Items.Add(item);
}
}} }}
} }
} }
Cell FindCell(float num_pos_x, float num_pos_y) { Cell GetCell(int cell_x, int cell_y) {
if ( num_pos_x < 0.0f || num_pos_y < 0.0f ) { var cell_index = cell_x + _gridNumPosCount.x * cell_y;
return null;
}
if ( num_pos_x >= _gridNumPosCount.x || num_pos_y >= _gridNumPosCount.y ) {
return null;
}
var cell_index = (int)(num_pos_x + _gridNumPosCount.x * num_pos_y);
return _gridCells[cell_index]; return _gridCells[cell_index];
} }
} }

View File

@@ -25,14 +25,14 @@ namespace IsoTools.Internal {
return item.Internal.ScreenBounds; return item.Internal.ScreenBounds;
} }
public void SetMinMaxCells(IsoObject item, Vector2 min, Vector2 max) { public void SetMinMaxCells(IsoObject item, IsoPoint2 min, IsoPoint2 max) {
item.Internal.MinSector = min; item.Internal.MinGridCell = min;
item.Internal.MaxSector = max; item.Internal.MaxGridCell = max;
} }
public void GetMinMaxCells(IsoObject item, ref Vector2 min, ref Vector2 max) { public void GetMinMaxCells(IsoObject item, ref IsoPoint2 min, ref IsoPoint2 max) {
min = item.Internal.MinSector; min = item.Internal.MinGridCell;
max = item.Internal.MaxSector; max = item.Internal.MaxGridCell;
} }
} }
@@ -148,8 +148,8 @@ namespace IsoTools.Internal {
ClearIsoObjectDepends(iso_object); ClearIsoObjectDepends(iso_object);
_gridLookUpper.Setup(iso_object); _gridLookUpper.Setup(iso_object);
_visibleGrid.LookUpCells( _visibleGrid.LookUpCells(
iso_object.Internal.MinSector, iso_object.Internal.MinGridCell,
iso_object.Internal.MaxSector, iso_object.Internal.MaxGridCell,
_gridLookUpper); _gridLookUpper);
_gridLookUpper.Reset(); _gridLookUpper.Reset();
} }

View File

@@ -194,10 +194,10 @@ namespace IsoTools {
public bool Dirty = false; public bool Dirty = false;
public bool Placed = false; public bool Placed = false;
public IsoRect ScreenBounds = IsoRect.zero; public IsoRect ScreenBounds = IsoRect.zero;
public IsoPoint2 MinGridCell = IsoPoint2.zero;
public IsoPoint2 MaxGridCell = IsoPoint2.zero;
public IsoMinMax MinMax3d = IsoMinMax.zero; public IsoMinMax MinMax3d = IsoMinMax.zero;
public float Offset3d = 0.0f; public float Offset3d = 0.0f;
public Vector2 MinSector = Vector2.zero;
public Vector2 MaxSector = Vector2.zero;
public Transform Transform = null; public Transform Transform = null;
public Vector2 LastTrans = Vector2.zero; public Vector2 LastTrans = Vector2.zero;
public List<Renderer> Renderers = new List<Renderer>(); public List<Renderer> Renderers = new List<Renderer>();