// Do not call this, its meant fo internal use public bool DoNotUse__CommitInternal() { // early return if (FontInst == null) return false; bool didReallocate = false; var geomData = new tk2dTextGeomGen.GeomData(data, currentNumberOfCharacters); if (geomData.ReallocRequired) { // volatile data int numVertices; int numIndices; geomData.GetTextMeshGeomDesc(out numVertices, out numIndices); if(vertices.Length != numVertices) { vertices = new Vector3[numVertices]; uvs = new Vector2[numVertices]; colors = new Color32[numVertices]; untintedColors = new Color32[numVertices]; if (FontInst.textureGradients) { uv2 = new Vector2[numVertices]; } triangles = new int[numIndices]; } currentNumberOfCharacters = geomData.RequiredAllocatedCharacters; geomData = new tk2dTextGeomGen.GeomData(data, currentNumberOfCharacters); geomData.SetTextMeshIndices(triangles, 0, 0); MeshClear(); didReallocate = true; } if ( (updateFlags & UpdateFlags.UpdateAll) != 0 || didReallocate ) { SetVertices(vertices, uvs, uv2, untintedColors, Application.isPlaying ? FontInst.resultMeshCustomOffset : data.Font.resultMeshCustomOffset, isRoundShiftDisabled, TotalShift, geomData); // update colors since untinted colors are changed if (!FontInst.isPacked) { SetColors(colors); } else { colors = untintedColors; } MeshVertices = vertices; MeshUV = uvs; if (font.textureGradients) { MeshUV2 = uv2; } MeshColors32 = colors; if (didReallocate) { MeshTriangles = triangles; } MeshRecalculateBounds(); MeshBounds = tk2dBaseSprite.AdjustedMeshBounds( MeshBounds, data.renderLayer ); } updateFlags = UpdateFlags.UpdateNone; return true; }
void BuildRenderMesh() { List <Material> materials = new List <Material>(); List <List <int> > indices = new List <List <int> >(); bool needNormals = false; bool needTangents = false; bool needUV2 = false; bool flattenDepth = CheckFlag(Flags.FlattenDepth); foreach (var bs in batchedSprites) { var spriteDef = bs.GetSpriteDefinition(); if (spriteDef != null) { needNormals |= (spriteDef.normals != null && spriteDef.normals.Length > 0); needTangents |= (spriteDef.tangents != null && spriteDef.tangents.Length > 0); } if (bs.type == tk2dBatchedSprite.Type.TextMesh) { tk2dTextMeshData textMeshData = allTextMeshData[bs.xRefId]; if ((textMeshData.Font != null) && textMeshData.FontInst.textureGradients) { needUV2 = true; } } } // just helpful to have these here, stop code being more messy List <int> bsNVerts = new List <int>(); List <int> bsNInds = new List <int>(); int numVertices = 0; foreach (var bs in batchedSprites) { if (!bs.IsDrawn) // when the first non-drawn child is found, it signals the end of the drawn list { break; } var spriteDef = bs.GetSpriteDefinition(); int nVerts = 0; int nInds = 0; switch (bs.type) { case tk2dBatchedSprite.Type.EmptyGameObject: break; case tk2dBatchedSprite.Type.Sprite: if (spriteDef != null) { tk2dSpriteGeomGen.GetSpriteGeomDesc(out nVerts, out nInds, spriteDef); } break; case tk2dBatchedSprite.Type.TiledSprite: if (spriteDef != null) { tk2dSpriteGeomGen.GetTiledSpriteGeomDesc(out nVerts, out nInds, spriteDef, bs.Dimensions); } break; case tk2dBatchedSprite.Type.SlicedSprite: if (spriteDef != null) { tk2dSpriteGeomGen.GetSlicedSpriteGeomDesc(out nVerts, out nInds, spriteDef, bs.CheckFlag(tk2dBatchedSprite.Flags.SlicedSprite_BorderOnly)); } break; case tk2dBatchedSprite.Type.ClippedSprite: if (spriteDef != null) { tk2dSpriteGeomGen.GetClippedSpriteGeomDesc(out nVerts, out nInds, spriteDef); } break; case tk2dBatchedSprite.Type.TextMesh: { tk2dTextMeshData textMeshData = allTextMeshData[bs.xRefId]; var geomData = new tk2dTextGeomGen.GeomData(textMeshData, 0); geomData.GetTextMeshGeomDesc(out nVerts, out nInds); break; } } numVertices += nVerts; bsNVerts.Add(nVerts); bsNInds.Add(nInds); } Vector3[] meshNormals = needNormals?new Vector3[numVertices]:null; Vector4[] meshTangents = needTangents?new Vector4[numVertices]:null; Vector3[] meshVertices = new Vector3[numVertices]; Color32[] meshColors = new Color32[numVertices]; Vector2[] meshUvs = new Vector2[numVertices]; Vector2[] meshUv2s = needUV2 ? new Vector2[numVertices] : null; int currVertex = 0; Material currentMaterial = null; List <int> currentIndices = null; Matrix4x4 scaleMatrix = Matrix4x4.identity; scaleMatrix.m00 = _scale.x; scaleMatrix.m11 = _scale.y; scaleMatrix.m22 = _scale.z; int bsIndex = 0; foreach (var bs in batchedSprites) { if (!bs.IsDrawn) // when the first non-drawn child is found, it signals the end of the drawn list { break; } if (bs.type == tk2dBatchedSprite.Type.EmptyGameObject) { ++bsIndex; // watch out for this continue; } var spriteDef = bs.GetSpriteDefinition(); int nVerts = bsNVerts[bsIndex]; int nInds = bsNInds[bsIndex]; Material material = GetMaterial(bs); // should have a material at this point if (material != currentMaterial) { if (currentMaterial != null) { materials.Add(currentMaterial); indices.Add(currentIndices); } currentMaterial = material; currentIndices = new List <int>(); } Vector3[] posData = new Vector3[nVerts]; Vector2[] uvData = new Vector2[nVerts]; Vector2[] uv2Data = needUV2 ? new Vector2[nVerts] : null; Color32[] colorData = new Color32[nVerts]; Vector3[] normalData = needNormals ? new Vector3[nVerts] : null; Vector4[] tangentData = needTangents ? new Vector4[nVerts] : null; int[] indData = new int[nInds]; Vector3 boundsCenter = Vector3.zero; Vector3 boundsExtents = Vector3.zero; switch (bs.type) { case tk2dBatchedSprite.Type.EmptyGameObject: break; case tk2dBatchedSprite.Type.Sprite: if (spriteDef != null) { tk2dSpriteGeomGen.SetSpriteGeom(posData, uvData, normalData, tangentData, 0, spriteDef, Vector3.one); tk2dSpriteGeomGen.SetSpriteIndices(indData, 0, currVertex, spriteDef); } break; case tk2dBatchedSprite.Type.TiledSprite: if (spriteDef != null) { tk2dSpriteGeomGen.SetTiledSpriteGeom(posData, uvData, 0, out boundsCenter, out boundsExtents, spriteDef, Vector3.one, bs.Dimensions, bs.anchor, bs.BoxColliderOffsetZ, bs.BoxColliderExtentZ); tk2dSpriteGeomGen.SetTiledSpriteIndices(indData, 0, currVertex, spriteDef, bs.Dimensions); } break; case tk2dBatchedSprite.Type.SlicedSprite: if (spriteDef != null) { tk2dSpriteGeomGen.SetSlicedSpriteGeom(posData, uvData, 0, out boundsCenter, out boundsExtents, spriteDef, Vector3.one, bs.Dimensions, bs.SlicedSpriteBorderBottomLeft, bs.SlicedSpriteBorderTopRight, bs.anchor, bs.BoxColliderOffsetZ, bs.BoxColliderExtentZ); tk2dSpriteGeomGen.SetSlicedSpriteIndices(indData, 0, currVertex, spriteDef, bs.CheckFlag(tk2dBatchedSprite.Flags.SlicedSprite_BorderOnly)); } break; case tk2dBatchedSprite.Type.ClippedSprite: if (spriteDef != null) { tk2dSpriteGeomGen.SetClippedSpriteGeom(posData, uvData, 0, out boundsCenter, out boundsExtents, spriteDef, Vector3.one, bs.ClippedSpriteRegionBottomLeft, bs.ClippedSpriteRegionTopRight, bs.BoxColliderOffsetZ, bs.BoxColliderExtentZ); tk2dSpriteGeomGen.SetClippedSpriteIndices(indData, 0, currVertex, spriteDef); } break; case tk2dBatchedSprite.Type.TextMesh: { tk2dTextMeshData textMeshData = allTextMeshData[bs.xRefId]; var geomData = new tk2dTextGeomGen.GeomData(textMeshData, 0); geomData.SetTextMeshGeom(posData, uvData, uv2Data, colorData, 0); if (!textMeshData.FontInst.isPacked) { Color32 topColor = textMeshData.color; Color32 bottomColor = textMeshData.useGradient ? textMeshData.color2 : textMeshData.color; for (int i = 0; i < colorData.Length; ++i) { Color32 c = ((i % 4) < 2) ? topColor : bottomColor; byte red = (byte)(((int)colorData[i].r * (int)c.r) / 255); byte green = (byte)(((int)colorData[i].g * (int)c.g) / 255); byte blue = (byte)(((int)colorData[i].b * (int)c.b) / 255); byte alpha = (byte)(((int)colorData[i].a * (int)c.a) / 255); if (textMeshData.FontInst.premultipliedAlpha) { red = (byte)(((int)red * (int)alpha) / 255); green = (byte)(((int)green * (int)alpha) / 255); blue = (byte)(((int)blue * (int)alpha) / 255); } colorData[i] = new Color32(red, green, blue, alpha); } } geomData.SetTextMeshIndices(indData, 0, currVertex); break; } } bs.CachedBoundsCenter = boundsCenter; bs.CachedBoundsExtents = boundsExtents; if (nVerts > 0 && bs.type != tk2dBatchedSprite.Type.TextMesh) { bool premulAlpha = (bs.spriteCollection != null) ? bs.spriteCollection.premultipliedAlpha : false; tk2dSpriteGeomGen.SetSpriteColors(colorData, 0, nVerts, bs.color, premulAlpha); } Matrix4x4 mat = scaleMatrix * bs.relativeMatrix; for (int i = 0; i < nVerts; ++i) { Vector3 pos = Vector3.Scale(posData[i], bs.baseScale); pos = mat.MultiplyPoint(pos); if (flattenDepth) { pos.z = 0; } meshVertices[currVertex + i] = pos; meshUvs[currVertex + i] = uvData[i]; if (needUV2) { meshUv2s[currVertex + i] = uv2Data[i]; } meshColors[currVertex + i] = colorData[i]; if (needNormals) { meshNormals[currVertex + i] = bs.rotation * normalData[i]; } if (needTangents) { Vector3 tang = new Vector3(tangentData[i].x, tangentData[i].y, tangentData[i].z); tang = bs.rotation * tang; meshTangents[currVertex + i] = new Vector4(tang.x, tang.y, tang.z, tangentData[i].w); } } currentIndices.AddRange(indData); currVertex += nVerts; ++bsIndex; } if (currentIndices != null) { materials.Add(currentMaterial); indices.Add(currentIndices); } if (mesh) { mesh.vertices = meshVertices; mesh.uv = meshUvs; if (needUV2) { mesh.uv2 = meshUv2s; } mesh.colors32 = meshColors; if (needNormals) { mesh.normals = meshNormals; } if (needTangents) { mesh.tangents = meshTangents; } mesh.subMeshCount = indices.Count; for (int i = 0; i < indices.Count; ++i) { mesh.SetTriangles(indices[i].ToArray(), i); } mesh.RecalculateBounds(); } GetComponent <Renderer>().sharedMaterials = materials.ToArray(); }