public void Draw(DrawingStage stage) { bool renderSingle = ((MainScreen)Owner).RenderSingle; if (Enabled || !renderSingle) { switch (stage) { case DrawingStage.Colour: { for (int i = 0; i < chunks.Count; i++) { if (CameraManager2D.CurrentCamera.IsInView(chunks[i].Bounds)) { LayerChunk chunk = chunks[i]; for (int j = 0; j < chunk.Indices.Count; j++) { if (cells[chunk.Indices[j]].Index != -1 && cells[chunk.Indices[j]].Index < sourceRects.Count) { Common.Batch.Draw(tileSheet, cells[chunk.Indices[j]].Bounds, sourceRects[cells[chunk.Indices[j]].Index], Color.White); } } } } } break; } } }
private LayerChunk GetParentLayer(LayerChunk layer) { if (layer.LayerChildLevel == 0) { return(null); } int childLevel = layer.LayerChildLevel; List <LayerChunk> layers = GetChunks <LayerChunk>(); int index = layers.IndexOf(layer); if (index < 0) { return(null); } for (int i = index - 1; i > 0; i--) { if (layers[i].LayerChildLevel == layer.LayerChildLevel - 1) { return(layers[i]); } } return(null); }
public override float ProcessCoordinate(LayerChunk layerChunk, float layerOpacity, int x, int y, float weight) { float getWeight = layerChunk.GetHeight(x, y); // Div weight by layer weight, check for 0 weight or 0 opacity to avoid division by 0 return((getWeight != 0 && layerOpacity != 0) ? weight / (getWeight * layerOpacity) : 0); }
public MetaData[] GetMetaData(Vector2 spritePivot, int pixelsPerUnit) { Dictionary <int, MetaData> metadatas = new Dictionary <int, MetaData>(); for (int index = 0; index < Frames.Count; index++) { List <LayerChunk> layers = GetChunks <LayerChunk>(); List <CelChunk> cels = Frames[index].GetChunks <CelChunk>(); cels.Sort((ca, cb) => ca.LayerIndex.CompareTo(cb.LayerIndex)); for (int i = 0; i < cels.Count; i++) { int layerIndex = cels[i].LayerIndex; LayerChunk layer = layers[layerIndex]; if (!layer.LayerName.StartsWith(MetaData.MetaDataChar)) //read only metadata layer { continue; } if (!metadatas.ContainsKey(layerIndex)) { metadatas[layerIndex] = new MetaData(layer.LayerName); } var metadata = metadatas[layerIndex]; CelChunk cel = cels[i]; Vector2 center = Vector2.zero; int pixelCount = 0; for (int y = 0; y < cel.Height; ++y) { for (int x = 0; x < cel.Width; ++x) { int texX = cel.X + x; int texY = -(cel.Y + y) + Header.Height - 1; var col = cel.RawPixelData[x + y * cel.Width]; if (col.GetColor().a > 0.1f) { center += new Vector2(texX, texY); pixelCount++; } } } if (pixelCount > 0) { center /= pixelCount; var pivot = Vector2.Scale(spritePivot, new Vector2(Header.Width, Header.Height)); var posWorld = (center - pivot) / pixelsPerUnit + Vector2.one * 0.5f / pixelsPerUnit; //center pos in middle of pixels metadata.Transforms.Add(index, posWorld); } } } return(metadatas.Values.ToArray()); }
void CreateChunks() { chunks.Clear(); int chunkRowLimit = CameraManager2D.CurrentCamera.View.Height / grid.CellSizeY; int chunkColLimit = CameraManager2D.CurrentCamera.View.Width / grid.CellSizeX; if (chunkRowLimit == 0) { chunkRowLimit = 1; } if (chunkColLimit == 0) { chunkColLimit = 1; } Vector2 initialPos = Vector2.Zero; float prevPosY = initialPos.Y; for (int y = 0; y < grid.Rows; y += chunkRowLimit) { for (int x = 0; x < grid.Columns; x += chunkColLimit) { LayerChunk chunk = new LayerChunk() { Bounds = new Rectangle( (int)initialPos.X, (int)initialPos.Y, grid.CellSizeX * chunkColLimit, grid.CellSizeY * chunkRowLimit), Indices = new List <int>() }; for (int i = 0; i < cells.Count; i++) { if (cells[i].Column >= x && cells[i].Column < x + chunkColLimit && cells[i].Row >= y && cells[i].Row < y + chunkRowLimit) { chunk.Indices.Add(i); } } chunks.Add(chunk); initialPos.X += chunkColLimit * grid.CellSizeY; } initialPos.Y += chunkRowLimit * grid.CellSizeY; initialPos.X = 0; } }
public Layer PropogateChunks(List <Vector2> ModifiedChunks) { Layer finalLayer = new Layer(LayerFunctionType.Normal, 0); // Temp array to hold working chunks LayerChunk[] propogated = new LayerChunk[ModifiedChunks.Count]; int cd = m_allLinkedAttributes.GetAttribute <int> ("ChunkDimensions"); int ctld = m_allLinkedAttributes.GetAttribute <int> ("ChunksToLoadDimensions"); for (int l = 0; l < ModifiedChunks.Count; ++l) { propogated [l] = new LayerChunk(cd); } // Now layer write has finished, propogate values down stack foreach (Layer layer in GameObject.FindGameObjectWithTag("LayerManager").GetComponent <Widget>().GetAttribute <List <Layer> >("Layers")) { // For each of the modified chunks per layers for (int l = 0; l < propogated.Length; ++l) { // For every height in the modified chunks for (int i = 0; i < cd; ++i) { for (int j = 0; j < cd; ++j) { // Pass the last working coord through the process function of the corresponding layer propogated [l].SetHeight(i, j, layer.m_layerFuntion.ProcessCoordinate(layer.m_layerChunks[(int)ModifiedChunks[l].x, (int)ModifiedChunks[l].y], layer.m_layerOpacity, i, j, propogated [l].GetHeight(i, j))); } } } } // Now sub brush step has finished (mouse button still down but changes this tick have finished, update all impacted chunks) for (int l = 0; l < ModifiedChunks.Count; ++l) { m_mapChunks [(int)ModifiedChunks[l].x, (int)ModifiedChunks[l].y].GetComponent <Chunk> ().UpdateMesh(propogated[l]); } if (ModifiedChunks.Count == ctld * ctld) { for (int i = 0; i < ctld; ++i) { for (int j = 0; j < ctld; ++j) { finalLayer.m_layerChunks [i, j] = propogated [(i * ctld) + j]; } } } GameObject.FindGameObjectWithTag("LayerManager").GetComponent <LayerManager>().ProjectSelectedLayer(); return(finalLayer); }
public MetaData(LayerChunk layer, int layerIndex) { Layer = layer; LayerIndex = layerIndex; var layerName = layer.LayerName; Args = new List <string>(); Transforms = new Dictionary <int, Vector2>(); // Check if it's a transform layer var regex = new Regex("@transform\\(\"(.*)\"\\)"); var match = regex.Match(layerName); if (match.Success) { Type = MetaDataType.TRANSFORM; Args.Add(match.Groups[1].Value); return; } // Check if secondary texture layer regex = new Regex("@secondary\\(\"(.*)\"\\)"); match = regex.Match(layerName); if (match.Success) { Type = MetaDataType.SECONDARY_TEXTURE; Args.Add(match.Groups[1].Value); return; } // Check if it's a shortcut for some common secondary textures if (layerName.Equals("@emission", StringComparison.OrdinalIgnoreCase)) { Type = MetaDataType.SECONDARY_TEXTURE; Args.Add("_Emission"); return; } if (layerName.Equals("@normal", StringComparison.OrdinalIgnoreCase)) { Type = MetaDataType.SECONDARY_TEXTURE; Args.Add("_NormalMap"); return; } // Unknown metadata layer Debug.LogWarning($"Unsupported aseprite metadata {layerName}"); }
public List <Texture2D> GetLayerTexture(int layerIndex, LayerChunk layer) { List <LayerChunk> layers = GetChunks <LayerChunk>(); List <Texture2D> textures = new List <Texture2D>(); for (int frameIndex = 0; frameIndex < Frames.Count; frameIndex++) { Frame frame = Frames[frameIndex]; List <CelChunk> cels = frame.GetChunks <CelChunk>(); for (int i = 0; i < cels.Count; i++) { if (cels[i].LayerIndex != layerIndex) { continue; } LayerBlendMode blendMode = layer.BlendMode; float opacity = Mathf.Min(layer.Opacity / 255f, cels[i].Opacity / 255f); bool visibility = layer.Visible; LayerChunk parent = GetParentLayer(layer); while (parent != null) { visibility &= parent.Visible; if (visibility == false) { break; } parent = GetParentLayer(parent); } if (visibility == false || layer.LayerType == LayerType.Group) { continue; } textures.Add(GetTextureFromCel(cels[i])); } } return(textures); }
// Call at the end of a mod tick, now array values have been changed public void UpdateMesh(LayerChunk baseChunk) { //Push the final weights and update the mesh m_chunkHeights = baseChunk.m_chunkHeights; // The new array of verts we are generating Vector3[] vertices = new Vector3[m_chunkDimension * m_chunkDimension]; // The new array of verts we are generating Vector3[] normals = new Vector3[m_chunkDimension * m_chunkDimension]; // Populate verts array for (int i = 0; i < m_chunkDimension; ++i) { for (int j = 0; j < m_chunkDimension; ++j) { // Set the heights from the height map, with the basic grid layout vertices [(i * m_chunkDimension) + j] = new Vector3(i, m_chunkHeights[i, j], j); normals [(i * m_chunkDimension) + j] = Vector3.up; } } Vector2[] uvs = new Vector2[vertices.Length]; for (int i = 0; i < uvs.Length; i++) { uvs[i] = new Vector2(vertices[i].x / 10, vertices[i].z / 10); } // Set the verts on our new mesh gameObject.GetComponent <MeshFilter> ().mesh.vertices = vertices; // Set the uvs on our new mesh gameObject.GetComponent <MeshFilter> ().mesh.uv = uvs; // Set the verts on our new mesh gameObject.GetComponent <MeshFilter> ().mesh.normals = normals; // Update the mesh collider at tick time gameObject.GetComponent <MeshCollider> ().sharedMesh = gameObject.GetComponent <MeshFilter> ().mesh; // Recalculate the chunk bounds, for culling gameObject.GetComponent <MeshFilter> ().mesh.RecalculateBounds(); }
// Blanks the array and modifiers public void ClearLayer() { if (m_activeModifierStack != null) { m_activeModifierStack.Clear(); } // Chunks to load dimensions int cd = GameObject.FindGameObjectWithTag("MapHandler").GetComponent <Widget> ().GetAttribute <int> ("ChunkDimensions"); int ctld = GameObject.FindGameObjectWithTag("MapHandler").GetComponent <Widget> ().GetAttribute <int> ("ChunksToLoadDimensions"); // Initialize chunk array m_layerChunks = new LayerChunk[ctld, ctld]; for (int i = 0; i < ctld; ++i) { for (int j = 0; j < ctld; ++j) { m_layerChunks [i, j] = new LayerChunk(cd); } } oddModChunk = GameObject.FindGameObjectWithTag("MapHandler").GetComponent <MapHandler> ().oddModChunk; oddMod = GameObject.FindGameObjectWithTag("MapHandler").GetComponent <MapHandler> ().oddMod; }
// For an x, y coordinate in a modifier array, do processing public virtual float ProcessCoordinate(LayerChunk layer, float layerOpacity, int x, int y, float weight) { // If base is called, just bomb 0 Debug.LogError("Base LayerFunction, process coordinate is virtual base method."); return(0); }
void CalculateChunks() { size = tileDeff.TileSize; int chunkRowLimit = (int)(Common.DefaultScreenResolution.Y / size.Y); int chunkColLimit = (int)(Common.DefaultScreenResolution.X / size.X); if (chunkColLimit == 0) { chunkColLimit = 1; } if (chunkRowLimit == 0) { chunkRowLimit = 1; } int currRow = 0; int currCol = 0; int prevRow = 0; int totalRows = tileDeff.Tiles.Length; int remainingRows = totalRows - chunkRowLimit; int maxColumns = GetMaxColumns(); Vector2 initialPos = new Vector2(0, Common.DefaultScreenResolution.Y - size.Y) + offset; float prevPosY = initialPos.Y; LayerChunk chunk = new LayerChunk(drawLayer, initialPos, this); chunk.Initialize(postRender, 0, 0, chunkColLimit, chunkRowLimit, out currCol, out currRow, out initialPos); chunks.Add(chunk); while (remainingRows > 0 || currCol < maxColumns) { if (currCol < maxColumns) { currRow = prevRow; initialPos.Y = prevPosY; } else if (currCol >= maxColumns) { currCol = 0; initialPos.X = offset.X; prevRow = currRow; if (currRow >= totalRows) { currRow = totalRows; remainingRows = 0; } else if (currRow < totalRows) { remainingRows -= chunkRowLimit; } } prevPosY = initialPos.Y; LayerChunk chnk = new LayerChunk(drawLayer, initialPos, this); chnk.Initialize(postRender, currCol, currRow, chunkColLimit, chunkRowLimit, out currCol, out currRow, out initialPos); chunks.Add(chnk); } }
public Texture2D GetFrame(int index) { Frame frame = Frames[index]; Texture2D texture = Texture2DUtil.CreateTransparentTexture(Header.Width, Header.Height); List <LayerChunk> layers = GetChunks <LayerChunk>(); List <CelChunk> cels = frame.GetChunks <CelChunk>(); cels.Sort((ca, cb) => ca.LayerIndex.CompareTo(cb.LayerIndex)); for (int i = 0; i < cels.Count; i++) { LayerChunk layer = layers[cels[i].LayerIndex]; LayerBlendMode blendMode = layer.BlendMode; float opacity = Mathf.Min(layer.Opacity / 255f, cels[i].Opacity / 255f); bool visibility = layer.Visible; LayerChunk parent = GetParentLayer(layer); while (parent != null) { visibility &= parent.Visible; if (visibility == false) { break; } parent = GetParentLayer(parent); } if (visibility == false || layer.LayerType == LayerType.Group) { continue; } Texture2D celTex = GetTextureFromCel(cels[i]); switch (blendMode) { case LayerBlendMode.Normal: texture = Texture2DBlender.Normal(texture, celTex); break; case LayerBlendMode.Multiply: texture = Texture2DBlender.Multiply(texture, celTex, opacity); break; case LayerBlendMode.Screen: texture = Texture2DBlender.Screen(texture, celTex); break; case LayerBlendMode.Overlay: texture = Texture2DBlender.Overlay(texture, celTex); break; case LayerBlendMode.Darken: texture = Texture2DBlender.Darken(texture, celTex); break; case LayerBlendMode.Lighten: texture = Texture2DBlender.Lighten(texture, celTex); break; case LayerBlendMode.ColorDodge: texture = Texture2DBlender.ColorDodge(texture, celTex); break; case LayerBlendMode.ColorBurn: texture = Texture2DBlender.ColorBurn(texture, celTex); break; case LayerBlendMode.HardLight: texture = Texture2DBlender.HardLight(texture, celTex); break; case LayerBlendMode.SoftLight: texture = Texture2DBlender.SoftLight(texture, celTex); break; case LayerBlendMode.Difference: texture = Texture2DBlender.Difference(texture, celTex); break; case LayerBlendMode.Exclusion: texture = Texture2DBlender.Exclusion(texture, celTex); break; case LayerBlendMode.Hue: texture = Texture2DBlender.Hue(texture, celTex); break; case LayerBlendMode.Saturation: texture = Texture2DBlender.Saturation(texture, celTex); break; case LayerBlendMode.Color: texture = Texture2DBlender.Color(texture, celTex); break; case LayerBlendMode.Luminosity: texture = Texture2DBlender.Luminosity(texture, celTex); break; case LayerBlendMode.Addition: texture = Texture2DBlender.Addition(texture, celTex); break; case LayerBlendMode.Subtract: texture = Texture2DBlender.Subtract(texture, celTex); break; case LayerBlendMode.Divide: texture = Texture2DBlender.Divide(texture, celTex); break; } } return(texture); }
public override float ProcessCoordinate(LayerChunk layerChunk, float layerOpacity, int x, int y, float weight) { // Simple addition return(weight * (layerChunk.GetHeight(x, y) * layerOpacity)); }
public override float ProcessCoordinate(LayerChunk layerChunk, float layerOpacity, int x, int y, float weight) { // Halfway between weights return(weight + (((weight - layerChunk.GetHeight(x, y)) / 2) * layerOpacity)); }