/// <summary> /// Returns 2 raised to the specified power. /// Provides at least 6 decimals of accuracy. /// </summary> internal static FP Pow2(FP x) { if (x.RawValue == 0) { return(FP.One); } // Avoid negative arguments by exploiting that exp(-x) = 1/exp(x). bool neg = x.RawValue < 0; if (neg) { x = -x; } if (x == FP.One) { return(neg ? FP.One / (FP)2 : (FP)2); } if (x >= FP.Log2Max) { return(neg ? FP.One / FP.MaxValue : FP.MaxValue); } if (x <= FP.Log2Min) { return(neg ? FP.MaxValue : FP.Zero); } /* The algorithm is based on the power series for exp(x): * http://en.wikipedia.org/wiki/Exponential_function#Formal_definition * * From term n, we get term n+1 by multiplying with x/n. * When the sum term drops to zero, we can stop summing. */ int integerPart = (int)Floor(x); // Take fractional part of exponent x = FP.FromRaw(x.RawValue & 0x00000000FFFFFFFF); var result = FP.One; var term = FP.One; int i = 1; while (term.RawValue != 0) { term = FP.FastMul(FP.FastMul(x, term), FP.Ln2) / (FP)i; result += term; i++; } result = FP.FromRaw(result.RawValue << integerPart); if (neg) { result = FP.One / result; } return(result); }
public void CreateFromString(string buffer) { int start = 0; string line = TextUtils.readLine(buffer, ref start); List <string> words = TextUtils.splitLine(line); bool isRightMap = false; if (words.Count == 2) { if (words[0] == "type" && words[1] == "octile") { isRightMap = true; } } if (isRightMap) { JumpFindPathWithGrid findPath = new JumpFindPathWithGrid(); findPath.Initialize(this); _path = findPath; //read grid file info string offsetx = TextUtils.readLine(buffer, ref start); words = TextUtils.splitLine(offsetx); FP offsetX = FP.FromRaw(long.Parse(words[1])); string offsety = TextUtils.readLine(buffer, ref start); words = TextUtils.splitLine(offsety); FP offsetY = FP.FromRaw(long.Parse(words[1])); _transformPosition = new TSVector(offsetX, 0f, offsetY); string width = TextUtils.readLine(buffer, ref start); words = TextUtils.splitLine(width); _nodeAmountX = int.Parse(words[1]); string height = TextUtils.readLine(buffer, ref start); words = TextUtils.splitLine(height); _nodeAmountY = int.Parse(words[1]); string size = TextUtils.readLine(buffer, ref start); words = TextUtils.splitLine(size); _nodeUnitSize = FP.FromRaw(long.Parse(words[1])); string nouseTag = TextUtils.readLine(buffer, ref start); //read file CreateGrid(_nodeAmountX, _nodeAmountY); for (int i = 0; i < _nodeAmountY; ++i) { string blocks = TextUtils.readLine(buffer, ref start); for (int j = 0; j < _nodeAmountX; ++j) { char v = blocks[j]; _grid[i, j].originalValue = v == '@' ? 1 : 0; } } } }
/// <summary> /// Returns the base-2 logarithm of a specified number. /// Provides at least 9 decimals of accuracy. /// </summary> /// <exception cref="ArgumentOutOfRangeException"> /// The argument was non-positive /// </exception> internal static FP Log2(FP x) { if (x.RawValue <= 0) { throw new ArgumentOutOfRangeException("Non-positive value passed to Ln", "x"); } // This implementation is based on Clay. S. Turner's fast binary logarithm // algorithm (C. S. Turner, "A Fast Binary Logarithm Algorithm", IEEE Signal // Processing Mag., pp. 124,140, Sep. 2010.) long b = 1U << (FP.FRACTIONAL_PLACES - 1); long y = 0; long rawX = x.RawValue; while (rawX < FP.ONE) { rawX <<= 1; y -= FP.ONE; } while (rawX >= (FP.ONE << 1)) { rawX >>= 1; y += FP.ONE; } var z = FP.FromRaw(rawX); for (int i = 0; i < FP.FRACTIONAL_PLACES; i++) { z = FP.FastMul(z, z); if (z.RawValue >= (FP.ONE << 1)) { z = FP.FromRaw(z.RawValue >> 1); y += b; } b >>= 1; } return(FP.FromRaw(y)); }
public static void Draw(Rect p, SerializedProperty prop, GUIContent label) { // grab value var f = FP.FromRaw(prop.longValue); var v = (Single)Math.Round(f.AsFloat, 5); // edit value try { var n = label == null?EditorGUI.FloatField(p, v) : EditorGUI.FloatField(p, label, v); if (n != v) { prop.longValue = FP.FromFloat_UNSAFE(n).RawValue; } GUI.Label(p, "(Fixed Point)", OverlayStyle); } catch (FormatException exn) { if (exn.Message != ".") { Debug.LogException(exn); } } }
public override void OnInspectorGUI() { var grid = target as Grid; GUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Grid Row"); grid.m_keepRow = EditorGUILayout.IntField(grid.m_keepRow); //("Grid Row", grid.m_keepRow, 1, 1024); GUILayout.EndHorizontal(); for (int i = 0; i < 100; ++i) { if (Grid.GridSizeDelta * i >= grid.m_keepRow) { grid.m_keepRow = Grid.GridSizeDelta * i; break; } } GUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Grid Column"); grid.m_keepColumn = EditorGUILayout.IntField(grid.m_keepColumn); //("Grid Column", grid.m_keepColumn, 1, 1024); GUILayout.EndHorizontal(); for (int j = 0; j < 100; ++j) { if (Grid.GridSizeDelta * j >= grid.m_keepColumn) { grid.m_keepColumn = Grid.GridSizeDelta * j; break; } } grid.GridSize = EditorGUILayout.Slider("Grid Size", grid.GridSize, 0.1f, 3.0f); GUILayout.BeginHorizontal(); if (GUILayout.Button("Resize")) { if (grid.m_keepRow != grid.Row || grid.m_keepColumn != grid.Column) { grid.Resize(grid.m_keepRow, grid.m_keepColumn); SceneView.RepaintAll(); } } if (GUILayout.Button("Fit to ground")) { grid.FitToGround(); SceneView.RepaintAll(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button("Export")) { string filepath = EditorUtility.SaveFilePanelInProject("Save Map", "GridInfo", "txt", "OKOK"); LogManager.Log(filepath); // string fileName = filepath;//文件名字 StringBuilder sb = new StringBuilder(); //offset sb.Append("type octile").Append("\r\n"); Vector3 offset = grid.transform.position; FP x = (FP)offset.x; sb.Append("X ").Append(x.RawValue).Append("\r\n"); FP z = (FP)offset.z; sb.Append("Z ").Append(z.RawValue).Append("\r\n"); sb.Append("width ").Append(grid.Column).Append("\r\n"); sb.Append("height ").Append(grid.Row).Append("\r\n"); FP size = (FP)grid.GridSize; sb.Append("size ").Append(size.RawValue).Append("\r\n"); sb.Append("map").Append("\r\n"); for (int i = 0; i < grid.Row; ++i) { for (int j = 0; j < grid.Column; ++j) { Cell c = grid.GetCell(i, j); if (c.collision == Cell.CollisionType.Unwalkable) { sb.Append('@'); } else { int ascCode = (int)c.material + '0'; sb.Append((char)ascCode); } } sb.Append("\r\n"); } //要写的数据源 EditorUtils.SaveTextFile(filepath, sb.ToString()); } if (GUILayout.Button("Import")) { string filepath = EditorUtility.OpenFilePanel("Load map", Application.dataPath, "txt"); if (filepath != null) { StreamReader reader = new StreamReader(filepath, new UTF8Encoding(false)); if (reader != null) { SWS.MapGridT myGrid = new SWS.MapGridT(); string content = reader.ReadToEnd(); int readPos = 0; List <string> kv = null; while (readPos < content.Length) { string line = EditorUtils.readLine(content, ref readPos); kv = EditorUtils.splitLine(line); if (kv.Count == 0) { continue; } if (kv[0] == "map") { break; } if (kv[0] == "X") { if (kv.Count > 1) { myGrid.X = FP.FromRaw(long.Parse(kv[1])); } } if (kv[0] == "Z") { if (kv.Count > 1) { myGrid.Z = FP.FromRaw(long.Parse(kv[1])); } } if (kv[0] == "width") { if (kv.Count > 1) { myGrid.Width = int.Parse(kv[1]); } } if (kv[0] == "height") { if (kv.Count > 1) { myGrid.Height = int.Parse(kv[1]); } } if (kv[0] == "size") { if (kv.Count > 1) { myGrid.GridSize = FP.FromRaw(long.Parse(kv[1])); } } } if (myGrid.Width == 0 || myGrid.Height == 0) { StringBuilder log = new StringBuilder(); log.Append("invlid width").Append(myGrid.Width).Append("or height").Append(myGrid.Height); LogManager.Log(log.ToString()); return; } grid.transform.position = new Vector3((float)myGrid.X, 0f, (float)myGrid.Z); grid.GridSize = (float)myGrid.GridSize; grid.Resize(myGrid.Height, myGrid.Width, false); grid.m_keepRow = myGrid.Height; grid.m_keepColumn = myGrid.Width; for (int i = 0; i < myGrid.Height; i++) { string line = EditorUtils.readLine(content, ref readPos); if (line.Length < myGrid.Width + 1) { StringBuilder log = new StringBuilder(); log.Append("line").Append(i).Append("length is less than").Append(myGrid.Width); LogManager.Log(log.ToString()); return; } for (int w = 0; w < myGrid.Width; w++) { Cell c = grid.GetCell(i, w); if (line[w] == '@') { grid.SetCellCollision(i, w, Cell.CollisionType.Unwalkable); } else { grid.SetCellCollision(i, w, Cell.CollisionType.Walkable); int enumNum = line[w] - '0'; c.material = (Cell.MaterialType)enumNum; } } } SceneView.RepaintAll(); } } } if (GUILayout.Button("MakeAllWalkable")) { // Grid grid = target as Grid; for (int i = 0; i < grid.Row; ++i) { for (int j = 0; j < grid.Column; ++j) { grid.SetCellCollision(i, j, Cell.CollisionType.Walkable); } } } if (GUILayout.Button("CreateFromPath")) { int walkNum = 0, nonWalkNum = 0; Polygon[] walkables = new Polygon[16]; for (int a = 0; a < walkables.Length; ++a) { walkables[a] = new Polygon(); } Polygon[] nonWalkables = new Polygon[32]; for (int b = 0; b < nonWalkables.Length; ++b) { nonWalkables[b] = new Polygon(); } //get all pathes WaypointManager manager = GameObject.FindObjectOfType <WaypointManager>(); if (manager) { Vector3 offset = grid.transform.position; PathManager[] pathes = manager.GetComponentsInChildren <PathManager>(); foreach (PathManager path in pathes) { if (path.walkable) { for (int i = 0; i < path.waypoints.Length; ++i) { Vector3 pos = path.waypoints[i].position; walkables[walkNum].m_Points.Add(new Vector2(pos.x - offset.x, pos.z - offset.z)); } Vector3 firstPos = path.waypoints[0].position; walkables[walkNum].m_Points.Add(new Vector2(firstPos.x - offset.x, firstPos.z - offset.z)); walkNum++; } else { for (int i = 0; i < path.waypoints.Length; ++i) { Vector3 pos = path.waypoints[i].position; nonWalkables[nonWalkNum].m_Points.Add(new Vector2(pos.x - offset.x, pos.z - offset.z)); } Vector3 firstPos = path.waypoints[0].position; nonWalkables[nonWalkNum].m_Points.Add(new Vector2(firstPos.x - offset.x, firstPos.z - offset.z)); nonWalkNum++; } } } //int[] gridData = editPlane.GetGridInfo(); for (int i = 0; i < grid.Row; i++) { for (int w = 0; w < grid.Column; w++) { float gridSize = grid.GridSize; bool processed = false; Vector2 pos = new Vector2(w * gridSize + gridSize * 0.5f, i * gridSize + gridSize * 0.5f); for (int nonWalkIndex = 0; nonWalkIndex < nonWalkNum; ++nonWalkIndex) { if (PtInPolygon(pos, nonWalkables[nonWalkIndex].m_Points)) { processed = true; grid.SetCellCollision(i, w, Cell.CollisionType.Unwalkable); } } if (!processed) { for (int walkIndex = 0; walkIndex < walkNum; ++walkIndex) { if (PtInPolygon(pos, walkables[walkIndex].m_Points)) { processed = true; grid.SetCellCollision(i, w, Cell.CollisionType.Walkable); } } } } } } GUILayout.EndHorizontal(); EditorGUILayout.Space(); GUILayout.Label("Brush Shap: "); GUILayout.BeginHorizontal(); if (GUILayout.Toggle((grid.m_brushType == Grid.BrushType.Rect1x1), "Rect1x1")) { grid.m_brushType = Grid.BrushType.Rect1x1; } if (GUILayout.Toggle((grid.m_brushType == Grid.BrushType.Rect3x3), "Rect3x3")) { grid.m_brushType = Grid.BrushType.Rect3x3; } if (GUILayout.Toggle((grid.m_brushType == Grid.BrushType.Rect5x5), "Rect5x5")) { grid.m_brushType = Grid.BrushType.Rect5x5; } if (GUILayout.Toggle((grid.m_brushType == Grid.BrushType.Rect7x7), "Rect7x7")) { grid.m_brushType = Grid.BrushType.Rect7x7; } if (GUILayout.Toggle((grid.m_brushType == Grid.BrushType.Rect9x9), "Rect9x9")) { grid.m_brushType = Grid.BrushType.Rect9x9; } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Toggle((grid.m_brushType == Grid.BrushType.Cross3x3), "Cross3x3")) { grid.m_brushType = Grid.BrushType.Cross3x3; } if (GUILayout.Toggle((grid.m_brushType == Grid.BrushType.Cross5x5), "Cross5x5")) { grid.m_brushType = Grid.BrushType.Cross5x5; } if (GUILayout.Toggle((grid.m_brushType == Grid.BrushType.Cross7x7), "Cross7x7")) { grid.m_brushType = Grid.BrushType.Cross7x7; } if (GUILayout.Toggle((grid.m_brushType == Grid.BrushType.Cross9x9), "Cross9x9")) { grid.m_brushType = Grid.BrushType.Cross9x9; } GUILayout.EndHorizontal(); EditorGUILayout.Space(); GUILayout.Label("Paint: "); GUILayout.BeginVertical(); var viewType = (Grid.ViewType)EditorGUILayout.EnumPopup( "View", grid.m_viewType); if (viewType != grid.m_viewType) { grid.ChangeView(viewType); } switch (grid.m_viewType) { case Grid.ViewType.WalkableView: grid.m_brushCollision = (Cell.CollisionType)EditorGUILayout.EnumPopup( "Collision", grid.m_brushCollision); break; case Grid.ViewType.SecurityView: grid.m_brushSecurity = (Cell.SecurityType)EditorGUILayout.EnumPopup( "Security", grid.m_brushSecurity); break; case Grid.ViewType.MaterialView: grid.m_brushMaterial = (Cell.MaterialType)EditorGUILayout.EnumPopup( "Material", grid.m_brushMaterial); break; } GUILayout.EndVertical(); }
public virtual void Deserialize(byte[] data) { int offset = 0; byte numberOfActions = data[offset++]; for (int i = 0; i < numberOfActions; i++) { byte key = data[offset++]; byte type = data[offset++]; switch (type) { case (byte)Types.Integer: int intValue = BitConverter.ToInt32(data, offset); AddInt(key, intValue); offset += sizeof(int); break; case (byte)Types.Byte: byte byteValue = data[offset++]; AddByte(key, byteValue); break; case (byte)Types.ByteArray: int byteArrayLen = BitConverter.ToInt32(data, offset); offset += sizeof(int); byte[] bArray = new byte[byteArrayLen]; for (int indexArray = 0; indexArray < byteArrayLen; indexArray++) { bArray[indexArray] = data[offset + indexArray]; } offset += byteArrayLen; AddByteArray(key, bArray); break; case (byte)Types.String: int strlen = BitConverter.ToInt32(data, offset); offset += sizeof(int); string stringValue = System.Text.Encoding.ASCII.GetString(data, offset, strlen); offset += strlen; AddString(key, stringValue); break; case (byte)Types.FP: FP fpValue = FP.FromRaw(BitConverter.ToInt64(data, offset)); AddFP(key, fpValue); offset += sizeof(long); break; case (byte)Types.TSVector: FP fpValueX = FP.FromRaw(BitConverter.ToInt64(data, offset)); offset += sizeof(long); FP fpValueY = FP.FromRaw(BitConverter.ToInt64(data, offset)); offset += sizeof(long); FP fpValueZ = FP.FromRaw(BitConverter.ToInt64(data, offset)); offset += sizeof(long); AddTSVector(key, new TSVector(fpValueX, fpValueY, fpValueZ)); break; case (byte)Types.TSVector2: FP fpValueX2 = FP.FromRaw(BitConverter.ToInt64(data, offset)); offset += sizeof(long); FP fpValueY2 = FP.FromRaw(BitConverter.ToInt64(data, offset)); offset += sizeof(long); AddTSVector2(key, new TSVector2(fpValueX2, fpValueY2)); break; default: //Not Implemented break; } } }