using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace WPM {
public class Cell {
#region Public properties
///
/// The index of this tile in the tiles list.
///
public int index;
///
/// The original points used to create the tile. Used internally. Use Vertices property to get the vertices in Vector3 format instead.
///
public Point[] vertexPoints;
///
/// Gets the center of this tile in local sphere coordinates.
///
public Vector3 sphereCenter;
///
/// Gets the vertices in local space coordinates. Note that the grid contains a few pentagons.
///
public Vector3[] vertices {
get {
if (!_verticesComputed) {
int l = vertexPoints.Length;
_vertices = new Vector3[l];
for (int k = 0; k < l; k++) {
_vertices[k] = vertexPoints[k].projectedVector3;
}
_verticesComputed = true;
}
return _vertices;
}
}
///
/// Gets the neighbours tiles.
///
public Cell[] neighbours {
get {
if (!_neighboursComputed) {
ComputeNeighbours();
}
return _neighbours;
}
}
///
/// Gets the vertices of the cell in lat/lon format
///
public Vector2[] latlon {
get {
if (_latlon == null) {
ComputeLatLonVertices();
}
return _latlon;
}
}
///
/// Returns the cell center in lat/lon coordinates
///
/// The latlon center.
public Vector2 latlonCenter {
get {
if (_latlonCenter.x >= UNKNOWN) {
_latlonCenter = Conversion.GetLatLonFromUnitSpherePoint(sphereCenter);
}
return _latlonCenter;
}
}
///
/// Gets the neighbours tiles indices.
///
public int[] neighboursIndices {
get {
if (!_neighboursComputed) {
ComputeNeighbours();
}
return _neighboursIndices;
}
}
///
/// Additional cost for crossing a neighbour tile.
///
public int[] neighboursCosts {
get {
if (_neighboursCosts == null) {
int neighbourCount = _neighbours != null ? _neighbours.Length : 6;
_neighboursCosts = new int[neighbourCount];
for (int k = 0; k < neighbourCount; k++) {
_neighboursCosts[k] = 0;
}
}
return _neighboursCosts;
}
}
///
/// Sets if this tile can be crossed when using PathFinding functions.
///
public bool canCross = true;
///
/// The tile mesh's renderer. Created when SetCellColor or SetCellTexture is used. Get the tile gameobject using renderer.gameObject
///
public Renderer renderer;
///
/// The base material assigned to this tile.
///
public Material customMat;
///
/// The temporary material assigned to this tile.
///
public Material tempMat;
///
/// Extrude amount for this tile. 0 = no extrusion, will render a flat tile which is faster.
///
public float extrudeAmount = 0f;
public int uvShadedChunkIndex;
public int uvShadedChunkStart;
public int uvShadedChunkLength;
public int uvWireChunkIndex;
public int uvWireChunkStart;
public int uvWireChunkLength;
///
/// Original value loaded from the heightmap
///
public float heightMapValue;
///
/// User-defined misc value (not used by Hexasphere)
///
public string tag;
///
/// If the tile is visible or not. Defaults to true.
///
public bool visible;
#endregion
#region Internal logic
Vector3[] _vertices;
bool _verticesComputed;
Point centerPoint;
Cell[] _neighbours;
int[] _neighboursIndices;
int[] _neighboursCosts;
bool _neighboursComputed;
static Triangle[] tempTriangles = new Triangle[20];
Vector2[] _latlon;
Vector2 _latlonCenter;
const float UNKNOWN = -99999;
public Cell(Point centerPoint, int index) {
this.index = index;
this.centerPoint = centerPoint;
this.centerPoint.tile = this;
this.sphereCenter = centerPoint.projectedVector3;
this.visible = true;
int facesCount = centerPoint.GetOrderedTriangles(tempTriangles);
vertexPoints = new Point[facesCount];
_latlonCenter.x = UNKNOWN;
for (int f = 0; f < facesCount; f++) {
vertexPoints[f] = tempTriangles[f].GetCentroid();
}
// resort if wrong order
if (facesCount == 6) {
Vector3 p0 = (Vector3)vertexPoints[0];
Vector3 p1 = (Vector3)vertexPoints[1];
Vector3 p5 = (Vector3)vertexPoints[5];
Vector3 v0 = p1 - p0;
Vector3 v1 = p5 - p0;
Vector3 cp = Vector3.Cross(v0, v1);
float dp = Vector3.Dot(cp, p1);
if (dp < 0) {
Point aux;
aux = vertexPoints[0];
vertexPoints[0] = vertexPoints[5];
vertexPoints[5] = aux;
aux = vertexPoints[1];
vertexPoints[1] = vertexPoints[4];
vertexPoints[4] = aux;
aux = vertexPoints[2];
vertexPoints[2] = vertexPoints[3];
vertexPoints[3] = aux;
}
} else if (facesCount == 5) {
Vector3 p0 = (Vector3)vertexPoints[0];
Vector3 p1 = (Vector3)vertexPoints[1];
Vector3 p4 = (Vector3)vertexPoints[4];
Vector3 v0 = p1 - p0;
Vector3 v1 = p4 - p0;
Vector3 cp = Vector3.Cross(v0, v1);
float dp = Vector3.Dot(cp, p1);
if (dp < 0) {
Point aux;
aux = vertexPoints[0];
vertexPoints[0] = vertexPoints[4];
vertexPoints[4] = aux;
aux = vertexPoints[1];
vertexPoints[1] = vertexPoints[3];
vertexPoints[3] = aux;
}
}
}
static List tempInt = new List(6);
static List temp = new List| (6);
void ComputeNeighbours() {
tempInt.Clear();
temp.Clear();
for (int k = 0; k < centerPoint.triangleCount; k++) {
Triangle other = centerPoint.triangles[k];
for (int j = 0; j < 3; j++) {
Cell tile = other.points[j].tile;
if (tile != null && !other.points[j].Equals(centerPoint) && !temp.Contains(tile)) {
temp.Add(tile);
tempInt.Add(tile.index);
}
}
}
_neighbours = temp.ToArray();
_neighboursIndices = tempInt.ToArray();
_neighboursComputed = true;
}
public int GetNeighbourCost(int neighbourIndex) {
if (_neighboursCosts == null || neighbourIndex < 0 || neighbourIndex >= _neighboursCosts.Length) {
return 0;
}
return _neighboursCosts[neighbourIndex];
}
void ComputeLatLonVertices() {
Vector3[] verts = vertices;
_latlon = new Vector2[verts.Length];
if (_latlon.Length > 0) {
for (int k = 0; k < verts.Length; k++) {
_latlon[k] = Conversion.GetLatLonFromUnitSpherePoint(verts[k]);
}
}
}
#endregion
}
} | |