public Resource(Tetris tetris, GameObject tetrisBlock, GameObject gameoverMark, Vector2[] blockUvList, Vector2[] blankUvList) { Stage stage = tetris.getStage(); m_tetris = tetris; int w = stage.getBoardWidth(); int h = stage.getBoardHeight(); m_blocks = new GameObject[w * h]; // 現状では落下ドロップは4個固定なので直値 m_minoBlocks = new GameObject[4]; for (int i = 0; i < 4; i++) { m_minoBlocks[i] = Instantiate(tetrisBlock); //m_minoBlocks[i].GetComponent<SpriteRenderer>().sortingOrder = LAYER_DROP; MeshQuad mesh = m_minoBlocks[i].GetComponent <MeshQuad>(); mesh.updateUv(blockUvList); } // 盤面の描画オブジェクトをあらかじめ用意 for (int i = 0; i < w * h; i++) { m_blocks[i] = Instantiate(tetrisBlock); //m_minoBlocks[i].GetComponent<SpriteRenderer>().sortingOrder = LAYER_DROP; MeshQuad mesh = m_blocks[i].GetComponent <MeshQuad>(); mesh.updateUv(blankUvList); } // ゲームオーバー表示 m_gameoverMark = Instantiate(gameoverMark); m_gameoverMark.GetComponent <SpriteRenderer>().sortingOrder = LAYER_GAMEOVER; }
public MeshQuad AddQuad(Vector3 a, Vector3 b, Vector3 c, Vector3 d, Color color) { MeshQuad quad = new MeshQuad(a, b, c, d, color); quads [numQuads] = quad; numQuads++; return(quad); }
public MeshQuad AddQuad(Vector2 size, Vector3 origin, Vector4 uvCoords, Color32 color, bool flippedXY) { MeshQuad quad = new MeshQuad(size, origin, uvCoords, color, flippedXY); quads [numQuads] = quad; numQuads++; return(quad); }
public void Execute(int i) { Vector3 ms = moveSpeed * i * deltaTime; MeshQuad s = ListV[i]; s.Move(ms); ListV[i] = s; }
/// <summary> /// 生成平面网格数据 /// </summary> /// <param name="rect">形状范围</param> /// <param name="blocks">要绘制的块</param> /// <param name="cellSize">单元格大小</param> /// <param name="gridOffset">位置偏移</param> /// <param name="vertices">输出顶点表</param> /// <param name="uv">输出uv表</param> /// <param name="triangles">输出绘制顺序</param> public static void MakePlaneMesh(RectInt rect, IList <Vector2Int> blocks, float cellSize, Vector3 gridOffset, out List <Vector3> vertices, out List <Vector2> uv, out List <int> triangles) { var quads = new List <MeshQuad>(); var vertexDic = new Dictionary <Vector3, Vertex>(); var id = 0; for (var y = 0; y <= rect.height; y++) { for (var x = 0; x <= rect.width; x++) { var xy = new Vector2Int(rect.x + x, rect.y + y); if (!blocks.Contains(xy)) { continue; } var quad = new MeshQuad(); quad.Vertex1 = new Vertex(0, new Vector3(xy.x, 0, xy.y) * cellSize + gridOffset, new Vector2((float)x / rect.width, (float)y / rect.height)); quad.Vertex2 = new Vertex(0, new Vector3(xy.x, 0, xy.y + 1) * cellSize + gridOffset, new Vector2((float)x / rect.width, (float)(y + 1) / rect.height)); quad.Vertex3 = new Vertex(0, new Vector3(xy.x + 1, 0, xy.y) * cellSize + gridOffset, new Vector2((float)(x + 1) / rect.width, (float)y / rect.height)); quad.Vertex4 = new Vertex(0, new Vector3(xy.x + 1, 0, xy.y + 1) * cellSize + gridOffset, new Vector2((float)(x + 1) / rect.width, (float)(y + 1) / rect.height)); quads.Add(quad); for (var i = 0; i < quad.Count; i++) { //if (vertexList.FindIndex((v) => v.Position == quad[i].Position) == -1) if (vertexDic.ContainsKey(quad[i].Position))// 使用散列表加快查找速度 { quad[i] = quad[i].SetID(vertexDic[quad[i].Position].ID); } else { // 若未找到相同位置的顶点则将该点添加到列表 quad[i] = quad[i].SetID(id++); vertexDic.Add(quad[i].Position, quad[i]); } } } } triangles = new List <int>(); vertices = new List <Vector3>(); uv = new List <Vector2>(); foreach (var vertex in vertexDic) { vertices.Add(vertex.Value.Position); uv.Add(vertex.Value.UV); } foreach (var quad in quads) { triangles.AddRange(quad.DrawOrder); } }
/** * 落下ブロックの描画 */ void drawTetrimino(Resource res) { Tetrimino tetrimino = res.tetris.getTetrimino(); GameObject[] blocks = res.minoBlocks; Tetrimino.Pattern pat = tetrimino.getPattern(); int num_blocks = 0; int index = 0; Vector2 offset = res.offset; int base_x, base_y; base_x = tetrimino.getPosX(); base_y = tetrimino.getPosY(); for (int y = 0; y < pat.h; y++) { for (int x = 0; x < pat.w; x++) { char c = pat.pat[index]; if (c == '1') { float posx = x + base_x + offset.x; float posy = y + base_y + offset.y; GameObject block = blocks[num_blocks]; block.transform.position = new Vector3(posx, posy, 0); //blk.GetComponent<Renderer>().material.color = m_colorList[tetrimino.getColorIndex()]; int color_index = tetrimino.getColorIndex(); MeshQuad mesh = block.GetComponent <MeshQuad>(); Color[] colors = new Color[] { m_colorList[color_index], m_colorList[color_index], m_colorList[color_index], m_colorList[color_index], }; mesh.updateUv(m_blockUvList); mesh.updateColor(colors); num_blocks++; } index++; } } }
void Start() { mesh = mf.mesh; Count = mesh.vertices.Length / 4; Listvv = new Vector3[Count * 4]; Listpt = new NativeArray <MeshQuad>(Count, Allocator.Persistent); for (int i = 0; i < Count; i++) { MeshQuad s = new MeshQuad(); s.SetA(mesh.vertices[i * 4]); s.SetB(mesh.vertices[i * 4 + 1]); s.SetC(mesh.vertices[i * 4 + 2]); s.SetD(mesh.vertices[i * 4 + 3]); Listpt[i] = s; } }
public void AddXZLine(Vector3 pointA, Vector3 pointB, float width, Color color) { Vector3 baseVector = (pointB - pointA).normalized.RotateLeftAboutY() * width; Vector3 a = pointA + baseVector; Vector3 b = pointA - baseVector; Vector3 c = pointB + baseVector; Vector3 d = pointB - baseVector; MeshQuad quad = new MeshQuad( a, b, c, d, new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 1), new Vector2(1, 1), Vector2.zero, Vector2.zero, Vector2.zero, Vector2.zero, Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero, color, color, color, color); AddQuad(quad); }
public void AddScenary(int x, int y, Sprite sprite) { Rect UVs = sprite.rect; UVs.x /= sprite.texture.width; UVs.width /= sprite.texture.width; UVs.y /= sprite.texture.height; UVs.height /= sprite.texture.height; float scaleW = UVs.width * sprite.texture.width; float scaleH = UVs.height * sprite.texture.height; Vector3 pos = new Vector3(x * 128, 0, y * 128); MeshQuad quad = new MeshQuad( pos, pos, pos, pos, new Vector2(UVs.x + UVs.width, UVs.y + UVs.height), new Vector2(UVs.x, UVs.y + UVs.height), new Vector2(UVs.x + UVs.width, UVs.y), new Vector2(UVs.x, UVs.y), new Vector2(scaleW, scaleH), new Vector2(scaleW, scaleH), new Vector2(scaleW, scaleH), new Vector2(scaleW, scaleH), new Vector3(-0.77f, -1.54f, 0), new Vector3(0.77f, -1.54f, 0), new Vector3(-0.77f, 0.0f, 0), new Vector3(0.77f, 0.0f, 0), Color.white, Color.white, Color.white, Color.white ); mesh.AddQuad(quad); }
public void UpdateGeometry(Vector3 velocity) { if (mesh != null) { mesh.Clear(); } mesh = new MeshHelper(1, "Game/truck", "LD32/TruckBillboard"); float tileX = 0.0f; float tileY = 0.0f; if (velocity.x > 0.1f) { tileX = 0.0f; tileY = 0.5f; } else if (velocity.x < -0.1f) { tileX = 0.5f; tileY = 0.0f; } else if (velocity.z > 0.1f) { tileX = 0.0f; tileY = 0.0f; } else { tileX = 0.5f; tileY = 0.5f; } MeshQuad quad = new MeshQuad( transform.position, transform.position, transform.position, transform.position, new Vector2(tileX + 0.5f, tileY + 0.5f), new Vector2(tileX + 0.0f, tileY + 0.5f), new Vector2(tileX + 0.5f, tileY + 0.0f), new Vector2(tileX + 0.0f, tileY + 0.0f), new Vector2(128, 0), new Vector2(128, 0), new Vector2(128, 0), new Vector2(128, 0), new Vector3(-0.77f, -0.77f, 0), new Vector3(0.77f, -0.77f, 0), new Vector3(-0.77f, 0.77f, 0), new Vector3(0.77f, 0.77f, 0), Color.white, Color.white, Color.white, Color.white ); mesh.AddQuad(quad); mesh.Commit(); }
protected async Task <Mesh> GenerateMesh(Chunk chunk, Chunk Xpos, Chunk Xneg, Chunk Ypos, Chunk Yneg, Chunk Zpos, Chunk Zneg) { uint vertCount = 0; Chunk[] neighbors = new Chunk[6] { Xpos, Xneg, Ypos, Yneg, Zpos, Zneg }; ////////////////////////////////////////// //// MESH CREATION ////////////////////////////////////////// Mesh _mesh = new Mesh(); List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); List <Vector2> uv2s = new List <Vector2>(); //List<Vector3> colors = new List<Vector3>(); List <int> indices = new List <int>(); await Task.Run(() => { // Tempory buffers // TODO: move me to thread pool int len = Chunk.SideLength; MeshQuad[,,,] quads = new MeshQuad[6, len, len, len]; int[,,] heads = new int[6, len, len]; int[,,] tails = new int[6, len, len]; int numMergedQuads = 0; int[,] mergedQuadPtr = new int[len, len]; MergedQuad[] mergedQuads = new MergedQuad[len *len]; // Initialization Array.Clear(quads, 0, quads.Length); Array.Clear(heads, 0, heads.Length); Array.Clear(tails, 0, tails.Length); ////////////////////////////////////////// //// EMIT FACES ////////////////////////////////////////// for (int x = 0; x < len; x++) { for (int y = 0; y < len; y++) { for (int z = 0; z < len; z++) { Block currentBlock = chunk.GetBlock(x, y, z); if (!currentBlock.IsRenderable()) { continue; } // empty or ignored // Ugly af Vector3Int currentPos = new Vector3Int(x, y, z); Vector3Int neighborPos; #region Emit faces // [X+, X-, Y+, Y-, Z+, Z-] for (int f = 0; f < 6; f++) { bool isNotBoundary = (f % 2 == 0) ? (currentPos[primaryIndex[f]] < (len - 1)) : (currentPos[primaryIndex[f]] > 0); // Reset Neighbor block in-chunk coordinate neighborPos = currentPos; // Neighbor block in self chunk if (isNotBoundary) { neighborPos[primaryIndex[f]] += direction[f]; if (chunk.GetBlock(neighborPos.x, neighborPos.y, neighborPos.z).IsSolid()) { continue; } } // Neighbor block in neighbor chunks else if (neighbors[f] != null) { neighborPos[primaryIndex[f]] = neighborIdx[f]; if (neighbors[f].GetBlock(neighborPos.x, neighborPos.y, neighborPos.z).IsSolid()) { continue; } } ///// Passed neighbor check, emit face ///// // Set block data quads[ f, currentPos[primaryIndex[f]], currentPos[secondaryIndex[f]], currentPos[thirdIndex[f]] ].block = currentBlock; // Set self as end quads[ f, currentPos[primaryIndex[f]], currentPos[secondaryIndex[f]], currentPos[thirdIndex[f]] ].next = currentPos[thirdIndex[f]]; // Link previous tail to self quads[ f, currentPos[primaryIndex[f]], currentPos[secondaryIndex[f]], tails[ f, currentPos[primaryIndex[f]], currentPos[secondaryIndex[f]] ] ].next = currentPos[thirdIndex[f]]; // Set head if not set if (heads[f, currentPos[primaryIndex[f]], currentPos[secondaryIndex[f]]] == 0) { heads[f, currentPos[primaryIndex[f]], currentPos[secondaryIndex[f]]] = currentPos[thirdIndex[f]] + 1; } // Move tail to self tails[ f, currentPos[primaryIndex[f]], currentPos[secondaryIndex[f]] ] = currentPos[thirdIndex[f]]; } #endregion } } } ////////////////////////////////////////// //// MERGE FACES ////////////////////////////////////////// // [X+, X-, Y+, Y-, Z+, Z-] for (int f = 0; f < 6; f++) { // Primary idx for (int i = 0; i < len; i++) { // Initilze slice Array.Clear(mergedQuadPtr, 0, mergedQuadPtr.Length); numMergedQuads = 0; // Secondary idx for (int j = 0; j < len; j++) { // Start from HEAD int k = heads[f, i, j] - 1; // Empty column j, ignore if (k < 0) { continue; } //if (quads[f, i, j, k].block.id == 0) { continue; } int continuous = 0; while (k < len) { continuous++; // Need to check if we having a new face if (quads[f, i, j, k].next != k + 1 || !Block.CanMergeRenderable(quads[f, i, j, quads[f, i, j, k].next].block, quads[f, i, j, k].block)) { // This column : from (k - continuous + 1) => (k + 1) Vector2Int minPt = new Vector2Int(j, k - continuous + 1); Vector2Int maxPt = new Vector2Int(j + 1, k + 1); // Check if can be merged with left if (j > 0 && (mergedQuadPtr[j - 1, k] > 0) && (Block.CanMergeRenderable(quads[f, i, j - 1, k].block, quads[f, i, j, k].block)) && (mergedQuads[mergedQuadPtr[j - 1, k] - 1].min.y == minPt.y) ) { mergedQuadPtr[j, k] = mergedQuadPtr[j - 1, k]; minPt = mergedQuads[mergedQuadPtr[j - 1, k] - 1].min; } // New merged face else { mergedQuadPtr[j, k] = numMergedQuads + 1; numMergedQuads++; } // Modify face information mergedQuads[mergedQuadPtr[j, k] - 1].block = quads[f, i, j, k].block; mergedQuads[mergedQuadPtr[j, k] - 1].min = minPt; mergedQuads[mergedQuadPtr[j, k] - 1].max = maxPt; continuous = 0; } // Check if is final if (quads[f, i, j, k].next == k) { break; } // Move to next quad k = quads[f, i, j, k].next; } //for (int k = 0; k < len; k++) //{ // if (quads[f, i, j, k].block.id == 0) { continue; } // // This column : from (k - continuous + 1) => (k + 1) // Vector2Int minPt = new Vector2Int(j, k); // Vector2Int maxPt = new Vector2Int(j + 1, k + 1); // mergedQuadPtr[j, k] = numMergedQuads; // numMergedQuads++; // mergedQuads[mergedQuadPtr[j, k]].block = quads[f, i, j, k].block; // mergedQuads[mergedQuadPtr[j, k]].min = minPt; // mergedQuads[mergedQuadPtr[j, k]].max = maxPt; //} } // Emit faces to mesh arrays for (int q = 0; q < numMergedQuads; q++) { var mQ = mergedQuads[q]; // Position Vector3 pt = new Vector3(); pt[primaryIndex[f]] = i + (direction[f] > 0 ? 1 : 0); pt[secondaryIndex[f]] = mQ.min.x; pt[thirdIndex[f]] = mQ.min.y; vertices.Add(pt); // (min.x, min.y) pt[thirdIndex[f]] = mQ.max.y; vertices.Add(pt); // (min.x, max.y) pt[secondaryIndex[f]] = mQ.max.x; vertices.Add(pt); // (max.x, max.y) pt[thirdIndex[f]] = mQ.min.y; vertices.Add(pt); // (max.x, min.y) // Normal pt = Vector3.zero; pt[primaryIndex[f]] = direction[f]; normals.Add(pt); normals.Add(pt); normals.Add(pt); normals.Add(pt); // UV // TODO: Values for testing - no textures now uvs.Add(new Vector2(0, 0)); uvs.Add(new Vector2(0, 1)); uvs.Add(new Vector2(1, 1)); uvs.Add(new Vector2(1, 0)); // Block data uv2s.Add(new Vector2(mQ.block.PackFloat(), 0)); uv2s.Add(new Vector2(mQ.block.PackFloat(), 0)); uv2s.Add(new Vector2(mQ.block.PackFloat(), 0)); uv2s.Add(new Vector2(mQ.block.PackFloat(), 0)); // Indices int vC = (int)vertCount; indices.Add(vC + indicesOrder[f, 0]); indices.Add(vC + indicesOrder[f, 1]); indices.Add(vC + indicesOrder[f, 2]); indices.Add(vC + indicesOrder[f, 0]); indices.Add(vC + indicesOrder[f, 2]); indices.Add(vC + indicesOrder[f, 3]); // Finish vertCount += 4; } } } }); ////////////////////////////////////////// //// MESH ASSEMBLY ////////////////////////////////////////// // TODO: ToArray() - performance good ? _mesh.vertices = vertices.ToArray(); _mesh.normals = normals.ToArray(); _mesh.uv = uvs.ToArray(); _mesh.uv2 = uv2s.ToArray(); _mesh.triangles = indices.ToArray(); return(_mesh); }
public MeshQuad AddQuad(MeshQuad quad) { quads [numQuads] = quad; numQuads++; return(quad); }
/** * 盤面の描画 */ void drawBoard(Resource res) { Stage stage = res.tetris.getStage(); int w = stage.getBoardWidth(); int h = stage.getBoardHeight(); int h_margin = stage.getBoardHeightMargin(); GameObject[] blocks = res.blocks; Stage.BlockInfo[,] board = stage.getBlockInfo(); Vector2 offset = res.offset; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { int index = x + y * w; bool isVisible = false; /* * if(null != blocks[index]) * { * GameObject.Destroy(blocks[index]); * blocks[index] = null; * }*/ GameObject block = blocks[index]; if (Stage.BLOCK_STATE.EXISTS == board[x, y].state) { //block = Instantiate(tetrisBlock); //block.GetComponent<Renderer>().material.color = m_colorList[board[x,y].color_index]; MeshQuad mesh = block.GetComponent <MeshQuad>(); Color[] colors = new Color[] { m_colorList[board[x, y].color_index], m_colorList[board[x, y].color_index], m_colorList[board[x, y].color_index], m_colorList[board[x, y].color_index], }; mesh.updateUv(m_blockUvList); mesh.updateColor(colors); //blocks[index] = block; isVisible = true; } else if (Stage.BLOCK_STATE.NONE == board[x, y].state) { // ブランクはマージン以外の領域に描画 if (y < h - h_margin) { // block = Instantiate(boardBlank); // blocks[index] = block; MeshQuad mesh = block.GetComponent <MeshQuad>(); Color[] colors = new Color[] { new Color(1, 1, 1, 1), new Color(1, 1, 1, 1), new Color(1, 1, 1, 1), new Color(1, 1, 1, 1), }; mesh.updateUv(m_blankUvList); mesh.updateColor(colors); isVisible = true; } // マージンを超えたブランクは非表示 } if (true == isVisible) { block.transform.position = new Vector3(x + offset.x, y + offset.y, 0); block.SetActive(true); } } } }