// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public override void OnInspectorGUI() { // ======================================================== // Base GUI // ======================================================== base.OnInspectorGUI(); GUILayout.Space(20); // ======================================================== // init values // ======================================================== // bool needRebuild = false; editSprite.spanim = editSprite.GetComponent <exSpriteAnimation>(); // get ElementInfo first Texture2D editTexture = exEditorHelper.LoadAssetFromGUID <Texture2D>(editSprite.textureGUID); // ======================================================== // Texture preview (input) // ======================================================== bool textureChanged = false; GUI.enabled = !inAnimMode; GUILayout.BeginHorizontal(); GUILayout.Space(20); EditorGUIUtility.LookLikeControls(); Texture2D newTexture = (Texture2D)EditorGUILayout.ObjectField(editTexture , typeof(Texture2D) , false , GUILayout.Width(100) , GUILayout.Height(100) ); EditorGUIUtility.LookLikeInspector(); if (newTexture != editTexture) { editTexture = newTexture; editSprite.textureGUID = exEditorHelper.AssetToGUID(editTexture); textureChanged = true; GUI.changed = true; } GUILayout.Space(10); GUILayout.BeginVertical(); GUILayout.Space(90); GUILayout.Label(editTexture ? editTexture.name : "None"); GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUI.enabled = true; // ======================================================== // get atlas element info from atlas database // ======================================================== exAtlas editAtlas = null; int editIndex = -1; exAtlasDB.ElementInfo elInfo = exAtlasDB.GetElementInfo(editSprite.textureGUID); if (elInfo != null) { editAtlas = exEditorHelper.LoadAssetFromGUID <exAtlas>(elInfo.guidAtlas); editIndex = elInfo.indexInAtlas; } bool useAtlas = editAtlas != null && editIndex != -1; // get atlas and index from textureGUID if (!EditorApplication.isPlaying) { // if we don't use atlas and current edit target use atlas, clear it. if (editSprite.useAtlas != useAtlas) { editSprite.Clear(); } // if we use atlas, check if the atlas,index changes if (useAtlas) { if (editAtlas != editSprite.atlas || editIndex != editSprite.index) { editSprite.SetSprite(editAtlas, editIndex); GUI.changed = true; } } // check if we are first time assignment if (useAtlas || editTexture != null) { if (isPrefab == false && editSprite.meshFilter.sharedMesh == null) { needRebuild = true; } } } // ======================================================== // get trimTexture // ======================================================== GUI.enabled = !inAnimMode && !useAtlas; bool newTrimTexture = EditorGUILayout.Toggle("Trim Texture", editSprite.trimTexture); if (!useAtlas && (textureChanged || newTrimTexture != editSprite.trimTexture)) { editSprite.GetComponent <Renderer>().sharedMaterial = exEditorHelper.GetDefaultMaterial(editTexture, editTexture.name); editSprite.trimTexture = newTrimTexture; // get trimUV Rect trimUV = new Rect(0, 0, 1, 1); if (editTexture != null) { if (editSprite.trimTexture) { if (exTextureHelper.IsValidForAtlas(editTexture) == false) { exTextureHelper.ImportTextureForAtlas(editTexture); } trimUV = exTextureHelper.GetTrimTextureRect(editTexture); trimUV = new Rect(trimUV.x / editTexture.width, (editTexture.height - trimUV.height - trimUV.y) / editTexture.height, trimUV.width / editTexture.width, trimUV.height / editTexture.height); } if (editSprite.customSize == false) { editSprite.width = trimUV.width * editTexture.width; editSprite.height = trimUV.height * editTexture.height; } } editSprite.trimUV = trimUV; editSprite.updateFlags |= exPlane.UpdateFlags.UV; editSprite.updateFlags |= exPlane.UpdateFlags.Vertex; } GUI.enabled = true; // ======================================================== // color // ======================================================== editSprite.color = EditorGUILayout.ColorField("Color", editSprite.color); // ======================================================== // atlas & index // ======================================================== GUILayout.BeginHorizontal(); GUI.enabled = false; EditorGUILayout.ObjectField("Atlas" , editSprite.atlas , typeof(exAtlas) , false ); GUI.enabled = true; GUI.enabled = !inAnimMode; if (GUILayout.Button("Edit...", GUILayout.Width(40), GUILayout.Height(15))) { exAtlasEditor editor = exAtlasEditor.NewWindow(); editor.Edit(editSprite.atlas); } GUI.enabled = true; GUILayout.EndHorizontal(); GUI.enabled = false; EditorGUILayout.IntField("Index", editSprite.index); GUI.enabled = true; // ======================================================== // custom size // ======================================================== GUI.enabled = !inAnimMode; editSprite.customSize = EditorGUILayout.Toggle("Custom Size", editSprite.customSize); GUI.enabled = true; // ======================================================== // width & height // ======================================================== ++EditorGUI.indentLevel; GUI.enabled = !inAnimMode && editSprite.customSize; // width float newWidth = EditorGUILayout.FloatField("Width", editSprite.width); if (newWidth != editSprite.width) { if (newWidth < 1.0f) { newWidth = 1.0f; } editSprite.width = newWidth; } // height float newHeight = EditorGUILayout.FloatField("Height", editSprite.height); if (newHeight != editSprite.height) { if (newHeight < 1.0f) { newHeight = 1.0f; } editSprite.height = newHeight; } --EditorGUI.indentLevel; // ======================================================== // Reset to original // ======================================================== GUILayout.BeginHorizontal(); GUILayout.Space(30); if (GUILayout.Button("Reset", GUILayout.Width(50))) { if (useAtlas) { exAtlas.Element el = editAtlas.elements[editIndex]; editSprite.width = el.trimRect.width; editSprite.height = el.trimRect.height; } else if (editTexture) { editSprite.width = editSprite.trimUV.width * editTexture.width; editSprite.height = editSprite.trimUV.height * editTexture.height; } GUI.changed = true; } GUILayout.EndHorizontal(); GUI.enabled = true; // ======================================================== // Rebuild button // ======================================================== GUI.enabled = !inAnimMode; GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Rebuild...", GUILayout.Height(20))) { needRebuild = true; } GUILayout.EndHorizontal(); GUI.enabled = true; GUILayout.Space(5); // if dirty, build it. if (!EditorApplication.isPlaying && !AnimationUtility.InAnimationMode()) { if (needRebuild) { EditorUtility.ClearProgressBar(); editSprite.Build(editTexture); } else if (GUI.changed) { if (editSprite.meshFilter.sharedMesh != null) { editSprite.UpdateMesh(editSprite.meshFilter.sharedMesh); } EditorUtility.SetDirty(editSprite); } } }
/////////////////////////////////////////////////////////////////////////////// // mesh building functions /////////////////////////////////////////////////////////////////////////////// // ------------------------------------------------------------------ /// \param _mesh the mesh to update /// /// Update the _mesh depends on the exPlane.updateFlags // ------------------------------------------------------------------ public void UpdateMesh(Mesh _mesh) { if (guiBorder_ == null) { updateFlags = UpdateFlags.None; return; } exAtlas.Element el = null; if (useAtlas) { el = atlas_.elements[index_]; } // ======================================================== // Update Vertex // ======================================================== if ((updateFlags & UpdateFlags.Vertex) != 0) { // init float widthScaled = width_ * scale_.x; float heightScaled = height_ * scale_.y; float halfWidthScaled = widthScaled * 0.5f; float halfHeightScaled = heightScaled * 0.5f; float offsetX = 0.0f; float offsetY = 0.0f; Vector3[] vertices = new Vector3[16]; switch (anchor_) { case Anchor.TopLeft: offsetX = -halfWidthScaled; offsetY = -halfHeightScaled; break; case Anchor.TopCenter: offsetX = 0.0f; offsetY = -halfHeightScaled; break; case Anchor.TopRight: offsetX = halfWidthScaled; offsetY = -halfHeightScaled; break; case Anchor.MidLeft: offsetX = -halfWidthScaled; offsetY = 0.0f; break; case Anchor.MidCenter: offsetX = 0.0f; offsetY = 0.0f; break; case Anchor.MidRight: offsetX = halfWidthScaled; offsetY = 0.0f; break; case Anchor.BotLeft: offsetX = -halfWidthScaled; offsetY = halfHeightScaled; break; case Anchor.BotCenter: offsetX = 0.0f; offsetY = halfHeightScaled; break; case Anchor.BotRight: offsetX = halfWidthScaled; offsetY = halfHeightScaled; break; default: offsetX = 0.0f; offsetY = 0.0f; break; } offsetX -= offset_.x; offsetY += offset_.y; float centerWidth = width_ - guiBorder_.border.horizontal; float centerHeight = height_ - guiBorder_.border.vertical; // calculate the base pos float x = -halfWidthScaled; float y = halfHeightScaled; float x0 = x; float x1 = x0 + guiBorder_.border.left * scale_.x; float x2 = x1 + centerWidth * scale_.x; float x3 = x2 + guiBorder_.border.right * scale_.x; float y0 = y; float y1 = y0 - guiBorder_.border.top * scale_.y; float y2 = y1 - centerHeight * scale_.y; float y3 = y2 - guiBorder_.border.bottom * scale_.y; // calculate the pos affect by anchor x0 -= offsetX; x1 -= offsetX; x2 -= offsetX; x3 -= offsetX; y0 += offsetY; y1 += offsetY; y2 += offsetY; y3 += offsetY; // build vertices vertices[0] = new Vector3(x0 + y0 * shear_.x, y0 + x0 * shear_.y, 0.0f); vertices[1] = new Vector3(x1 + y0 * shear_.x, y0 + x1 * shear_.y, 0.0f); vertices[2] = new Vector3(x2 + y0 * shear_.x, y0 + x2 * shear_.y, 0.0f); vertices[3] = new Vector3(x3 + y0 * shear_.x, y0 + x3 * shear_.y, 0.0f); vertices[4] = new Vector3(x0 + y1 * shear_.x, y1 + x0 * shear_.y, 0.0f); vertices[5] = new Vector3(x1 + y1 * shear_.x, y1 + x1 * shear_.y, 0.0f); vertices[6] = new Vector3(x2 + y1 * shear_.x, y1 + x2 * shear_.y, 0.0f); vertices[7] = new Vector3(x3 + y1 * shear_.x, y1 + x3 * shear_.y, 0.0f); vertices[8] = new Vector3(x0 + y2 * shear_.x, y2 + x0 * shear_.y, 0.0f); vertices[9] = new Vector3(x1 + y2 * shear_.x, y2 + x1 * shear_.y, 0.0f); vertices[10] = new Vector3(x2 + y2 * shear_.x, y2 + x2 * shear_.y, 0.0f); vertices[11] = new Vector3(x3 + y2 * shear_.x, y2 + x3 * shear_.y, 0.0f); vertices[12] = new Vector3(x0 + y3 * shear_.x, y3 + x0 * shear_.y, 0.0f); vertices[13] = new Vector3(x1 + y3 * shear_.x, y3 + x1 * shear_.y, 0.0f); vertices[14] = new Vector3(x2 + y3 * shear_.x, y3 + x2 * shear_.y, 0.0f); vertices[15] = new Vector3(x3 + y3 * shear_.x, y3 + x3 * shear_.y, 0.0f); // DELME { // // build vertices // switch ( plane ) { // case Plane.XY: // vertices[0] = new Vector3( x0 + y0 * shear_.x, y0 + x0 * shear_.y, 0.0f ); // vertices[1] = new Vector3( x1 + y0 * shear_.x, y0 + x1 * shear_.y, 0.0f ); // vertices[2] = new Vector3( x2 + y0 * shear_.x, y0 + x2 * shear_.y, 0.0f ); // vertices[3] = new Vector3( x3 + y0 * shear_.x, y0 + x3 * shear_.y, 0.0f ); // vertices[4] = new Vector3( x0 + y1 * shear_.x, y1 + x0 * shear_.y, 0.0f ); // vertices[5] = new Vector3( x1 + y1 * shear_.x, y1 + x1 * shear_.y, 0.0f ); // vertices[6] = new Vector3( x2 + y1 * shear_.x, y1 + x2 * shear_.y, 0.0f ); // vertices[7] = new Vector3( x3 + y1 * shear_.x, y1 + x3 * shear_.y, 0.0f ); // vertices[8] = new Vector3( x0 + y2 * shear_.x, y2 + x0 * shear_.y, 0.0f ); // vertices[9] = new Vector3( x1 + y2 * shear_.x, y2 + x1 * shear_.y, 0.0f ); // vertices[10] = new Vector3( x2 + y2 * shear_.x, y2 + x2 * shear_.y, 0.0f ); // vertices[11] = new Vector3( x3 + y2 * shear_.x, y2 + x3 * shear_.y, 0.0f ); // vertices[12] = new Vector3( x0 + y3 * shear_.x, y3 + x0 * shear_.y, 0.0f ); // vertices[13] = new Vector3( x1 + y3 * shear_.x, y3 + x1 * shear_.y, 0.0f ); // vertices[14] = new Vector3( x2 + y3 * shear_.x, y3 + x2 * shear_.y, 0.0f ); // vertices[15] = new Vector3( x3 + y3 * shear_.x, y3 + x3 * shear_.y, 0.0f ); // break; // case Plane.XZ: // vertices[0] = new Vector3( x0 + y0 * shear_.x, 0.0f, y0 + x0 * shear_.y ); // vertices[1] = new Vector3( x1 + y0 * shear_.x, 0.0f, y0 + x1 * shear_.y ); // vertices[2] = new Vector3( x2 + y0 * shear_.x, 0.0f, y0 + x2 * shear_.y ); // vertices[3] = new Vector3( x3 + y0 * shear_.x, 0.0f, y0 + x3 * shear_.y ); // vertices[4] = new Vector3( x0 + y1 * shear_.x, 0.0f, y1 + x0 * shear_.y ); // vertices[5] = new Vector3( x1 + y1 * shear_.x, 0.0f, y1 + x1 * shear_.y ); // vertices[6] = new Vector3( x2 + y1 * shear_.x, 0.0f, y1 + x2 * shear_.y ); // vertices[7] = new Vector3( x3 + y1 * shear_.x, 0.0f, y1 + x3 * shear_.y ); // vertices[8] = new Vector3( x0 + y2 * shear_.x, 0.0f, y2 + x0 * shear_.y ); // vertices[9] = new Vector3( x1 + y2 * shear_.x, 0.0f, y2 + x1 * shear_.y ); // vertices[10] = new Vector3( x2 + y2 * shear_.x, 0.0f, y2 + x2 * shear_.y ); // vertices[11] = new Vector3( x3 + y2 * shear_.x, 0.0f, y2 + x3 * shear_.y ); // vertices[12] = new Vector3( x0 + y3 * shear_.x, 0.0f, y3 + x0 * shear_.y ); // vertices[13] = new Vector3( x1 + y3 * shear_.x, 0.0f, y3 + x1 * shear_.y ); // vertices[14] = new Vector3( x2 + y3 * shear_.x, 0.0f, y3 + x2 * shear_.y ); // vertices[15] = new Vector3( x3 + y3 * shear_.x, 0.0f, y3 + x3 * shear_.y ); // break; // case Plane.ZY: // vertices[0] = new Vector3( 0.0f, y0 + x0 * shear_.y, x0 + y0 * shear_.x ); // vertices[1] = new Vector3( 0.0f, y0 + x1 * shear_.y, x1 + y0 * shear_.x ); // vertices[2] = new Vector3( 0.0f, y0 + x2 * shear_.y, x2 + y0 * shear_.x ); // vertices[3] = new Vector3( 0.0f, y0 + x3 * shear_.y, x3 + y0 * shear_.x ); // // vertices[4] = new Vector3( 0.0f, y1 + x0 * shear_.y, x0 + y1 * shear_.x ); // vertices[5] = new Vector3( 0.0f, y1 + x1 * shear_.y, x1 + y1 * shear_.x ); // vertices[6] = new Vector3( 0.0f, y1 + x2 * shear_.y, x2 + y1 * shear_.x ); // vertices[7] = new Vector3( 0.0f, y1 + x3 * shear_.y, x3 + y1 * shear_.x ); // // vertices[8] = new Vector3( 0.0f, y2 + x0 * shear_.y, x0 + y2 * shear_.x ); // vertices[9] = new Vector3( 0.0f, y2 + x1 * shear_.y, x1 + y2 * shear_.x ); // vertices[10] = new Vector3( 0.0f, y2 + x2 * shear_.y, x2 + y2 * shear_.x ); // vertices[11] = new Vector3( 0.0f, y2 + x3 * shear_.y, x3 + y2 * shear_.x ); // // vertices[12] = new Vector3( 0.0f, y3 + x0 * shear_.y, x0 + y3 * shear_.x ); // vertices[13] = new Vector3( 0.0f, y3 + x1 * shear_.y, x1 + y3 * shear_.x ); // vertices[14] = new Vector3( 0.0f, y3 + x2 * shear_.y, x2 + y3 * shear_.x ); // vertices[15] = new Vector3( 0.0f, y3 + x3 * shear_.y, x3 + y3 * shear_.x ); // break; // } // } DELME end _mesh.vertices = vertices; _mesh.bounds = GetMeshBounds(offsetX, offsetY, halfWidthScaled * 2.0f, halfHeightScaled * 2.0f); // update collider if we have UpdateBoundRect(offsetX, offsetY, halfWidthScaled * 2.0f, halfHeightScaled * 2.0f); if (collisionHelper) { collisionHelper.UpdateCollider(); } } // ======================================================== // Update UV // ======================================================== if ((updateFlags & UpdateFlags.UV) != 0) { Vector2[] uvs = new Vector2[16]; // if the sprite is in an atlas if (el != null) { float xStart = el.coords.x; float yStart = el.coords.y; float xEnd = el.coords.xMax; float yEnd = el.coords.yMax; float leftRatio = (float)guiBorder_.border.left / (float)atlas_.texture.width; float rightRatio = (float)guiBorder_.border.right / (float)atlas_.texture.width; float topRatio = (float)guiBorder_.border.top / (float)atlas_.texture.height; float bottomRatio = (float)guiBorder_.border.bottom / (float)atlas_.texture.height; float u0 = xStart; float u1 = xStart + leftRatio; float u2 = xEnd - rightRatio; float u3 = xEnd; float v0 = yEnd; float v1 = yEnd - topRatio; float v2 = yStart + bottomRatio; float v3 = yStart; uvs[0] = new Vector2(u0, v0); uvs[1] = new Vector2(u1, v0); uvs[2] = new Vector2(u2, v0); uvs[3] = new Vector2(u3, v0); uvs[4] = new Vector2(u0, v1); uvs[5] = new Vector2(u1, v1); uvs[6] = new Vector2(u2, v1); uvs[7] = new Vector2(u3, v1); uvs[8] = new Vector2(u0, v2); uvs[9] = new Vector2(u1, v2); uvs[10] = new Vector2(u2, v2); uvs[11] = new Vector2(u3, v2); uvs[12] = new Vector2(u0, v3); uvs[13] = new Vector2(u1, v3); uvs[14] = new Vector2(u2, v3); uvs[15] = new Vector2(u3, v3); } else { float xStart = 0.0f; float yStart = 0.0f; float xEnd = 1.0f; float yEnd = 1.0f; Texture texture = GetComponent <Renderer>().sharedMaterial.mainTexture; float leftRatio = (float)guiBorder_.border.left / (float)texture.width; float rightRatio = (float)guiBorder_.border.right / (float)texture.width; float topRatio = (float)guiBorder_.border.top / (float)texture.height; float bottomRatio = (float)guiBorder_.border.bottom / (float)texture.height; float u0 = xStart; float u1 = xStart + leftRatio; float u2 = xEnd - rightRatio; float u3 = xEnd; float v0 = yEnd; float v1 = yEnd - topRatio; float v2 = yStart + bottomRatio; float v3 = yStart; uvs[0] = new Vector2(u0, v0); uvs[1] = new Vector2(u1, v0); uvs[2] = new Vector2(u2, v0); uvs[3] = new Vector2(u3, v0); uvs[4] = new Vector2(u0, v1); uvs[5] = new Vector2(u1, v1); uvs[6] = new Vector2(u2, v1); uvs[7] = new Vector2(u3, v1); uvs[8] = new Vector2(u0, v2); uvs[9] = new Vector2(u1, v2); uvs[10] = new Vector2(u2, v2); uvs[11] = new Vector2(u3, v2); uvs[12] = new Vector2(u0, v3); uvs[13] = new Vector2(u1, v3); uvs[14] = new Vector2(u2, v3); uvs[15] = new Vector2(u3, v3); } _mesh.uv = uvs; } // ======================================================== // Update Color // ======================================================== if ((updateFlags & UpdateFlags.Color) != 0) { Color[] colors = new Color[16]; for (int i = 0; i < 16; ++i) { colors[i] = color_; } _mesh.colors = colors; } // ======================================================== // Update Index // ======================================================== if ((updateFlags & UpdateFlags.Index) != 0) { int[] indices = new int[6 * 9]; for (int i = 0; i < 3; ++i) { int vid = 4 * i; for (int j = 0; j < 3; ++j) { int vert_id = vid + j; int idx_id = 6 * (i * 3 + j); indices[idx_id + 0] = vert_id + 0; indices[idx_id + 1] = vert_id + 1; indices[idx_id + 2] = vert_id + 4; indices[idx_id + 3] = vert_id + 4; indices[idx_id + 4] = vert_id + 1; indices[idx_id + 5] = vert_id + 5; } } _mesh.triangles = indices; } // NOTE: though we set updateFlags to None at exPlane::LateUpdate, // the Editor still need this or it will caused editor keep dirty updateFlags = UpdateFlags.None; }
// ------------------------------------------------------------------ /// \param _atlasInfo the atlas info /// \param _noImport if true, ex2D will not import the texture to fit for atlas /// build the atlas info to atlas // ------------------------------------------------------------------ public static void Build(exAtlasInfo _atlasInfo, bool _noImport = false) { exAtlas atlas = _atlasInfo.atlas; Texture2D texture = _atlasInfo.texture; Material material = _atlasInfo.material; // check if the atlas info is valid for build if (atlas == null) { Debug.LogError("Failed to build atlas info " + _atlasInfo.name + ", the atlas is missing!"); return; } if (texture == null) { Debug.LogError("Failed to build atlas info " + _atlasInfo.name + ", the texture is missing!"); return; } if (material == null) { Debug.LogError("Failed to build atlas info " + _atlasInfo.name + ", the material is missing!"); return; } // if (_atlasInfo.needLayout) { _atlasInfo.LayoutElements(); _atlasInfo.needLayout = false; } // create temp texture Color32 buildColor = new Color(0.0f, 0.0f, 0.0f, 0.0f); if (_atlasInfo.useBuildColor) { buildColor = new Color(_atlasInfo.buildColor.r, _atlasInfo.buildColor.g, _atlasInfo.buildColor.b, 0.0f); } string path = AssetDatabase.GetAssetPath(texture); TextureImporter importer = TextureImporter.GetAtPath(path) as TextureImporter; // TextureImporterSettings textureImporterSettings = new TextureImporterSettings(); // importer.ReadTextureSettings(textureImporterSettings); // textureImporterSettings.readable = true; // importer.SetTextureSettings(textureImporterSettings); importer.wrapMode = TextureWrapMode.Clamp; importer.isReadable = true; AssetDatabase.ImportAsset(path); Color32[] colors = new Color32[_atlasInfo.width * _atlasInfo.height]; for (int i = 0; i < _atlasInfo.width * _atlasInfo.height; ++i) { colors[i] = buildColor; } texture.SetPixels32(colors); try { EditorUtility.DisplayProgressBar("Building Atlas " + _atlasInfo.name, "Building Atlas...", 0.1f); // build atlas texture _atlasInfo.elements.Sort(exAtlasInfo.CompareByName); FillAtlasTexture(texture, _atlasInfo, _noImport); EditorUtility.DisplayProgressBar("Building Atlas " + _atlasInfo.name, "Import Atlas", 0.9f); // write to disk byte[] pngData = texture.EncodeToPNG(); if (pngData != null) { File.WriteAllBytes(path, pngData); } // now we finish atlas texture filling, we should turn off Read/Write settings, that will save memory a lot! TextureImporter importSettings = TextureImporter.GetAtPath(path) as TextureImporter; importSettings.wrapMode = TextureWrapMode.Clamp; importSettings.isReadable = _atlasInfo.readable; AssetDatabase.ImportAsset(path); // atlas.elements = new exAtlas.Element[_atlasInfo.elements.Count]; for (int i = 0; i < _atlasInfo.elements.Count; ++i) { exAtlasInfo.Element el = _atlasInfo.elements[i]; exAtlas.Element el2 = new exAtlas.Element(); int coord_x = el.coord[0]; int coord_y = el.atlasInfo.height - el.coord[1] - (int)el.Height(); float xStart = (float)coord_x / (float)el.atlasInfo.width; float yStart = (float)coord_y / (float)el.atlasInfo.height; float xEnd = (float)(coord_x + el.Width()) / (float)el.atlasInfo.width; float yEnd = (float)(coord_y + el.Height()) / (float)el.atlasInfo.height; el2.name = el.texture.name; el2.coords = new Rect(xStart, yStart, xEnd - xStart, yEnd - yStart); el2.rotated = el.rotated; el2.originalWidth = el.texture.width; el2.originalHeight = el.texture.height; el2.trimRect = el.trimRect; atlas.elements[i] = el2; // update the index in exAtlasDB if (el.isFontElement == false) { exAtlasDB.UpdateElementInfo(el, i); } } atlas.texture = texture; atlas.material = material; EditorUtility.SetDirty(atlas); EditorUtility.ClearProgressBar(); } catch (System.Exception) { EditorUtility.ClearProgressBar(); throw; } // save the needRebuild setting _atlasInfo.needRebuild = false; EditorUtility.SetDirty(_atlasInfo); }
// ------------------------------------------------------------------ /// \param _atlas the new atlas /// \param _index the index of the element in the new atlas /// Set a new picture in an atlas to this sprite // ------------------------------------------------------------------ public void SetSprite(exAtlas _atlas, int _index) { bool checkVertex = false; bool createMesh = false; // pre-check if (_atlas == null || _atlas.elements == null || _index < 0 || _index >= _atlas.elements.Length) { Debug.LogWarning("Invalid input in SetSprite. atlas = " + (_atlas ? _atlas.name : "null") + ", index = " + _index); return; } // it is possible that the atlas is null and we don't have mesh if (atlas_ == null) { createMesh = true; } // if (atlas_ != _atlas) { atlas_ = _atlas; renderer.sharedMaterial = _atlas.material; updateFlags |= UpdateFlags.UV; checkVertex = true; } // if (index_ != _index) { index_ = _index; updateFlags |= UpdateFlags.UV; checkVertex = true; } // if (checkVertex) { // NOTE: if we use texture offset, it always need to update vertex if (useTextureOffset_) { updateFlags |= UpdateFlags.Vertex; } if (!customSize_) { exAtlas.Element el = atlas_.elements[index_]; float newWidth = el.trimRect.width; float newHeight = el.trimRect.height; // float newWidth = el.coords.width * atlas_.texture.width; // float newHeight = el.coords.height * atlas_.texture.height; if (el.rotated) { float tmp = newWidth; newWidth = newHeight; newHeight = tmp; } if (newWidth != width_ || newHeight != height_) { width_ = newWidth; height_ = newHeight; updateFlags |= UpdateFlags.Vertex; } } } // if (createMesh) { // create mesh ( in editor, this can duplicate mesh to prevent shared mesh for sprite) meshFilter_.mesh = new Mesh(); updateFlags = UpdateFlags.Vertex | UpdateFlags.UV | UpdateFlags.Color | UpdateFlags.Index; // check if update mesh collider MeshCollider meshCollider = collider as MeshCollider; if (meshCollider && meshCollider.sharedMesh == null) { this.UpdateColliderSize(0.2f); } } }
// ------------------------------------------------------------------ /// \param _mesh the mesh to update /// /// Update the _mesh depends on the exPlane.updateFlags // ------------------------------------------------------------------ public void UpdateMesh(Mesh _mesh) { exAtlas.Element el = null; if (useAtlas) { el = atlas_.elements[index_]; } // ======================================================== // get clip info first // ======================================================== float clipLeft = 0.0f; float clipRight = 0.0f; float clipTop = 0.0f; float clipBottom = 0.0f; if (clipInfo_.clipped) { if (scale_.x >= 0.0f) { clipLeft = clipInfo_.left; clipRight = clipInfo_.right; } else { clipLeft = clipInfo_.right; clipRight = clipInfo_.left; } if (scale_.y >= 0.0f) { clipTop = clipInfo_.top; clipBottom = clipInfo_.bottom; } else { clipTop = clipInfo_.bottom; clipBottom = clipInfo_.top; } } // ======================================================== // Update Vertex // ======================================================== if ((updateFlags & UpdateFlags.Vertex) != 0) { Vector2 finalScale = new Vector2(scale_.x * ppfScale_.x, scale_.y * ppfScale_.y); // init float halfWidthScaled = width_ * finalScale.x * 0.5f; float halfHeightScaled = height_ * finalScale.y * 0.5f; float offsetX = 0.0f; float offsetY = 0.0f; Vector3[] vertices = new Vector3[4]; Vector3[] normals = new Vector3[4]; // TEMP // calculate anchor offset if (useTextureOffset_) { // get original width and height float originalWidth = 0.0f; float originalHeight = 0.0f; Rect trimRect = new Rect(0, 0, 1, 1); if (el != null) { originalWidth = el.originalWidth * finalScale.x; originalHeight = el.originalHeight * finalScale.y; trimRect = new Rect(el.trimRect.x * finalScale.x, el.trimRect.y * finalScale.y, el.trimRect.width * finalScale.x, el.trimRect.height * finalScale.y); } else { if (renderer.sharedMaterial != null) { Texture texture = renderer.sharedMaterial.mainTexture; originalWidth = texture.width * finalScale.x; originalHeight = texture.height * finalScale.y; trimRect = new Rect(trimUV.x * originalWidth, (1.0f - trimUV.height - trimUV.y) * originalHeight, trimUV.width * originalWidth, trimUV.height * originalHeight); } } switch (anchor_) { // case Anchor.TopLeft: offsetX = -halfWidthScaled - trimRect.x; offsetY = -halfHeightScaled - trimRect.y; break; case Anchor.TopCenter: offsetX = (originalWidth - trimRect.width) * 0.5f - trimRect.x; offsetY = -halfHeightScaled - trimRect.y; break; case Anchor.TopRight: offsetX = halfWidthScaled + originalWidth - trimRect.xMax; offsetY = -halfHeightScaled - trimRect.y; break; // case Anchor.MidLeft: offsetX = -halfWidthScaled - trimRect.x; offsetY = (originalHeight - trimRect.height) * 0.5f - trimRect.y; break; case Anchor.MidCenter: offsetX = (originalWidth - trimRect.width) * 0.5f - trimRect.x; offsetY = (originalHeight - trimRect.height) * 0.5f - trimRect.y; break; case Anchor.MidRight: offsetX = halfWidthScaled + originalWidth - trimRect.xMax; offsetY = (originalHeight - trimRect.height) * 0.5f - trimRect.y; break; // case Anchor.BotLeft: offsetX = -halfWidthScaled - trimRect.x; offsetY = halfHeightScaled + originalHeight - trimRect.yMax; break; case Anchor.BotCenter: offsetX = (originalWidth - trimRect.width) * 0.5f - trimRect.x; offsetY = halfHeightScaled + originalHeight - trimRect.yMax; break; case Anchor.BotRight: offsetX = halfWidthScaled + originalWidth - trimRect.xMax; offsetY = halfHeightScaled + originalHeight - trimRect.yMax; break; default: offsetX = (originalWidth - trimRect.width) * 0.5f - trimRect.x; offsetY = (originalHeight - trimRect.height) * 0.5f - trimRect.y; break; } } else { switch (anchor_) { case Anchor.TopLeft: offsetX = -halfWidthScaled; offsetY = -halfHeightScaled; break; case Anchor.TopCenter: offsetX = 0.0f; offsetY = -halfHeightScaled; break; case Anchor.TopRight: offsetX = halfWidthScaled; offsetY = -halfHeightScaled; break; case Anchor.MidLeft: offsetX = -halfWidthScaled; offsetY = 0.0f; break; case Anchor.MidCenter: offsetX = 0.0f; offsetY = 0.0f; break; case Anchor.MidRight: offsetX = halfWidthScaled; offsetY = 0.0f; break; case Anchor.BotLeft: offsetX = -halfWidthScaled; offsetY = halfHeightScaled; break; case Anchor.BotCenter: offsetX = 0.0f; offsetY = halfHeightScaled; break; case Anchor.BotRight: offsetX = halfWidthScaled; offsetY = halfHeightScaled; break; default: offsetX = 0.0f; offsetY = 0.0f; break; } } offsetX -= offset_.x; offsetY += offset_.y; // float xMinClip = finalScale.x * width_ * (-0.5f + clipLeft); float xMaxClip = finalScale.x * width_ * (0.5f - clipRight); float yMinClip = finalScale.y * height_ * (-0.5f + clipTop); float yMaxClip = finalScale.y * height_ * (0.5f - clipBottom); // build vertices & normals for (int r = 0; r < 2; ++r) { for (int c = 0; c < 2; ++c) { int i = r * 2 + c; float x, y; CalculateVertex(out x, out y, width_ * finalScale.x, height_ * finalScale.y, c, r, xMinClip, xMaxClip, yMinClip, yMaxClip, offsetX, offsetY); vertices[i] = new Vector3(x, y, 0.0f); normals[i] = new Vector3(0.0f, 0.0f, -1.0f); // TEMP } } _mesh.vertices = vertices; _mesh.normals = normals; // TEMP _mesh.bounds = GetMeshBounds(offsetX, offsetY, halfWidthScaled * 2.0f, halfHeightScaled * 2.0f); // update collider if we have UpdateBoundRect(offsetX, offsetY, halfWidthScaled * 2.0f, halfHeightScaled * 2.0f); if (collisionHelper) { collisionHelper.UpdateCollider(); } // #if UNITY_EDITOR // _mesh.RecalculateBounds(); // #endif } // ======================================================== // Update UV // ======================================================== if ((updateFlags & UpdateFlags.UV) != 0) { Vector2[] uvs = new Vector2[4]; // if the sprite is in an atlas if (el != null) { float xStart = el.coords.x; float yStart = el.coords.y; float xEnd = el.coords.xMax; float yEnd = el.coords.yMax; // do uv clip if (clipInfo_.clipped) { xStart += el.coords.width * clipLeft; yStart += el.coords.height * clipTop; xEnd -= el.coords.width * clipRight; yEnd -= el.coords.height * clipBottom; } if (el.rotated) { uvs[0] = new Vector2(xEnd, yEnd); uvs[1] = new Vector2(xEnd, yStart); uvs[2] = new Vector2(xStart, yEnd); uvs[3] = new Vector2(xStart, yStart); } else { uvs[0] = new Vector2(xStart, yEnd); uvs[1] = new Vector2(xEnd, yEnd); uvs[2] = new Vector2(xStart, yStart); uvs[3] = new Vector2(xEnd, yStart); } } else { float xStart = trimUV.x; float yStart = trimUV.y; float xEnd = trimUV.xMax; float yEnd = trimUV.yMax; // do uv clip if (clipInfo_.clipped) { xStart += trimUV.width * clipLeft; yStart += trimUV.height * clipTop; xEnd -= trimUV.width * clipRight; yEnd -= trimUV.height * clipBottom; } uvs[0] = new Vector2(xStart, yEnd); uvs[1] = new Vector2(xEnd, yEnd); uvs[2] = new Vector2(xStart, yStart); uvs[3] = new Vector2(xEnd, yStart); } _mesh.uv = uvs; } // ======================================================== // Update Color // ======================================================== if ((updateFlags & UpdateFlags.Color) != 0) { Color[] colors = new Color[4]; for (int i = 0; i < 4; ++i) { colors[i] = color_; } _mesh.colors = colors; } // ======================================================== // Update Index // ======================================================== if ((updateFlags & UpdateFlags.Index) != 0) { int[] indices = new int[6]; indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 2; indices[4] = 1; indices[5] = 3; _mesh.triangles = indices; } // NOTE: though we set updateFlags to None at exPlane::LateUpdate, // the Editor still need this or it will caused editor keep dirty updateFlags = UpdateFlags.None; }
/////////////////////////////////////////////////////////////////////////////// // mesh building functions /////////////////////////////////////////////////////////////////////////////// // ------------------------------------------------------------------ /// \param _mesh the mesh to update /// /// Update the _mesh depends on the exPlane.updateFlags // ------------------------------------------------------------------ public void UpdateMesh(Mesh _mesh) { if (guiBorder_ == null) { updateFlags = UpdateFlags.None; return; } exAtlas.Element el = null; if (useAtlas) { el = atlas_.elements[index_]; } // ======================================================== // get clip info first // ======================================================== float clipLeft = 0.0f; float clipRight = 0.0f; float clipTop = 0.0f; float clipBottom = 0.0f; if (clipInfo_.clipped) { if (scale_.x >= 0.0f) { clipLeft = clipInfo_.left; clipRight = clipInfo_.right; } else { clipLeft = clipInfo_.right; clipRight = clipInfo_.left; } if (scale_.y >= 0.0f) { clipTop = clipInfo_.top; clipBottom = clipInfo_.bottom; } else { clipTop = clipInfo_.bottom; clipBottom = clipInfo_.top; } } // ======================================================== // Update Vertex // ======================================================== if ((updateFlags & UpdateFlags.Vertex) != 0) { // init float widthScaled = width_ * scale_.x; float heightScaled = height_ * scale_.y; float halfWidthScaled = widthScaled * 0.5f; float halfHeightScaled = heightScaled * 0.5f; float offsetX = 0.0f; float offsetY = 0.0f; Vector3[] vertices = new Vector3[16]; switch (anchor_) { case Anchor.TopLeft: offsetX = -halfWidthScaled; offsetY = -halfHeightScaled; break; case Anchor.TopCenter: offsetX = 0.0f; offsetY = -halfHeightScaled; break; case Anchor.TopRight: offsetX = halfWidthScaled; offsetY = -halfHeightScaled; break; case Anchor.MidLeft: offsetX = -halfWidthScaled; offsetY = 0.0f; break; case Anchor.MidCenter: offsetX = 0.0f; offsetY = 0.0f; break; case Anchor.MidRight: offsetX = halfWidthScaled; offsetY = 0.0f; break; case Anchor.BotLeft: offsetX = -halfWidthScaled; offsetY = halfHeightScaled; break; case Anchor.BotCenter: offsetX = 0.0f; offsetY = halfHeightScaled; break; case Anchor.BotRight: offsetX = halfWidthScaled; offsetY = halfHeightScaled; break; default: offsetX = 0.0f; offsetY = 0.0f; break; } offsetX -= offset_.x; offsetY += offset_.y; // float xMinClip = scale_.x * width_ * (-0.5f + clipLeft); float xMaxClip = scale_.x * width_ * (0.5f - clipRight); float yMinClip = scale_.y * height_ * (-0.5f + clipTop); float yMaxClip = scale_.y * height_ * (0.5f - clipBottom); float centerWidth = width_ - guiBorder_.border.horizontal; float centerHeight = height_ - guiBorder_.border.vertical; // calculate the base pos float x = -halfWidthScaled; float y = halfHeightScaled; float x0 = x; float x1 = x0 + guiBorder_.border.left * scale_.x; float x2 = x1 + centerWidth * scale_.x; float x3 = x2 + guiBorder_.border.right * scale_.x; float y0 = y; float y1 = y0 - guiBorder_.border.top * scale_.y; float y2 = y1 - centerHeight * scale_.y; float y3 = y2 - guiBorder_.border.bottom * scale_.y; // do clip if (clipInfo_.clipped) { // xMinClip if (x2 <= xMinClip) { clipLeft = (xMinClip - x3) / (guiBorder_.border.right * scale_.x); x0 = xMinClip; x1 = xMinClip; x2 = xMinClip; } else if (x1 <= xMinClip) { clipLeft = 0.0f; // FIXME x0 = xMinClip; x1 = xMinClip; } else if (x0 <= xMinClip) { clipLeft = (xMinClip - x0) / (float)(guiBorder_.border.left * scale_.x); x0 = xMinClip; } // xMaxClip if (x1 >= xMaxClip) { clipRight = (x0 - xMaxClip) / (guiBorder_.border.left * scale_.x); x1 = xMaxClip; x2 = xMaxClip; x3 = xMaxClip; } else if (x2 >= xMaxClip) { clipRight = 0.0f; // FIXME x2 = xMaxClip; x3 = xMaxClip; } else if (x3 >= xMaxClip) { clipRight = (x3 - xMaxClip) / (guiBorder_.border.right * scale_.x); x3 = xMaxClip; } // yMinClip if (y1 <= yMinClip) { clipTop = (yMinClip - y0) / (guiBorder_.border.bottom * scale_.y); y1 = yMinClip; y2 = yMinClip; y3 = yMinClip; } else if (y2 <= yMinClip) { clipTop = 0.0f; // FIXME y2 = yMinClip; y3 = yMinClip; } else if (y3 <= yMinClip) { clipTop = (yMinClip - y3) / (guiBorder_.border.top * scale_.y); y3 = yMinClip; } // yMaxClip if (y2 >= yMaxClip) { clipBottom = (y3 - yMaxClip) / (guiBorder_.border.top * scale_.y); y0 = yMaxClip; y1 = yMaxClip; y2 = yMaxClip; } else if (y1 >= yMaxClip) { clipBottom = 0.0f; // FIXME y0 = yMaxClip; y1 = yMaxClip; } else if (y0 >= yMaxClip) { clipBottom = (y0 - yMaxClip) / (guiBorder_.border.bottom * scale_.y); y0 = yMaxClip; } } // calculate the pos affect by anchor x0 -= offsetX; x1 -= offsetX; x2 -= offsetX; x3 -= offsetX; y0 += offsetY; y1 += offsetY; y2 += offsetY; y3 += offsetY; // build vertices vertices[0] = new Vector3(x0 + y0 * shear_.x, y0 + x0 * shear_.y, 0.0f); vertices[1] = new Vector3(x1 + y0 * shear_.x, y0 + x1 * shear_.y, 0.0f); vertices[2] = new Vector3(x2 + y0 * shear_.x, y0 + x2 * shear_.y, 0.0f); vertices[3] = new Vector3(x3 + y0 * shear_.x, y0 + x3 * shear_.y, 0.0f); vertices[4] = new Vector3(x0 + y1 * shear_.x, y1 + x0 * shear_.y, 0.0f); vertices[5] = new Vector3(x1 + y1 * shear_.x, y1 + x1 * shear_.y, 0.0f); vertices[6] = new Vector3(x2 + y1 * shear_.x, y1 + x2 * shear_.y, 0.0f); vertices[7] = new Vector3(x3 + y1 * shear_.x, y1 + x3 * shear_.y, 0.0f); vertices[8] = new Vector3(x0 + y2 * shear_.x, y2 + x0 * shear_.y, 0.0f); vertices[9] = new Vector3(x1 + y2 * shear_.x, y2 + x1 * shear_.y, 0.0f); vertices[10] = new Vector3(x2 + y2 * shear_.x, y2 + x2 * shear_.y, 0.0f); vertices[11] = new Vector3(x3 + y2 * shear_.x, y2 + x3 * shear_.y, 0.0f); vertices[12] = new Vector3(x0 + y3 * shear_.x, y3 + x0 * shear_.y, 0.0f); vertices[13] = new Vector3(x1 + y3 * shear_.x, y3 + x1 * shear_.y, 0.0f); vertices[14] = new Vector3(x2 + y3 * shear_.x, y3 + x2 * shear_.y, 0.0f); vertices[15] = new Vector3(x3 + y3 * shear_.x, y3 + x3 * shear_.y, 0.0f); // DELME { // // build vertices // switch ( plane ) { // case Plane.XY: // vertices[0] = new Vector3( x0 + y0 * shear_.x, y0 + x0 * shear_.y, 0.0f ); // vertices[1] = new Vector3( x1 + y0 * shear_.x, y0 + x1 * shear_.y, 0.0f ); // vertices[2] = new Vector3( x2 + y0 * shear_.x, y0 + x2 * shear_.y, 0.0f ); // vertices[3] = new Vector3( x3 + y0 * shear_.x, y0 + x3 * shear_.y, 0.0f ); // vertices[4] = new Vector3( x0 + y1 * shear_.x, y1 + x0 * shear_.y, 0.0f ); // vertices[5] = new Vector3( x1 + y1 * shear_.x, y1 + x1 * shear_.y, 0.0f ); // vertices[6] = new Vector3( x2 + y1 * shear_.x, y1 + x2 * shear_.y, 0.0f ); // vertices[7] = new Vector3( x3 + y1 * shear_.x, y1 + x3 * shear_.y, 0.0f ); // vertices[8] = new Vector3( x0 + y2 * shear_.x, y2 + x0 * shear_.y, 0.0f ); // vertices[9] = new Vector3( x1 + y2 * shear_.x, y2 + x1 * shear_.y, 0.0f ); // vertices[10] = new Vector3( x2 + y2 * shear_.x, y2 + x2 * shear_.y, 0.0f ); // vertices[11] = new Vector3( x3 + y2 * shear_.x, y2 + x3 * shear_.y, 0.0f ); // vertices[12] = new Vector3( x0 + y3 * shear_.x, y3 + x0 * shear_.y, 0.0f ); // vertices[13] = new Vector3( x1 + y3 * shear_.x, y3 + x1 * shear_.y, 0.0f ); // vertices[14] = new Vector3( x2 + y3 * shear_.x, y3 + x2 * shear_.y, 0.0f ); // vertices[15] = new Vector3( x3 + y3 * shear_.x, y3 + x3 * shear_.y, 0.0f ); // break; // case Plane.XZ: // vertices[0] = new Vector3( x0 + y0 * shear_.x, 0.0f, y0 + x0 * shear_.y ); // vertices[1] = new Vector3( x1 + y0 * shear_.x, 0.0f, y0 + x1 * shear_.y ); // vertices[2] = new Vector3( x2 + y0 * shear_.x, 0.0f, y0 + x2 * shear_.y ); // vertices[3] = new Vector3( x3 + y0 * shear_.x, 0.0f, y0 + x3 * shear_.y ); // vertices[4] = new Vector3( x0 + y1 * shear_.x, 0.0f, y1 + x0 * shear_.y ); // vertices[5] = new Vector3( x1 + y1 * shear_.x, 0.0f, y1 + x1 * shear_.y ); // vertices[6] = new Vector3( x2 + y1 * shear_.x, 0.0f, y1 + x2 * shear_.y ); // vertices[7] = new Vector3( x3 + y1 * shear_.x, 0.0f, y1 + x3 * shear_.y ); // vertices[8] = new Vector3( x0 + y2 * shear_.x, 0.0f, y2 + x0 * shear_.y ); // vertices[9] = new Vector3( x1 + y2 * shear_.x, 0.0f, y2 + x1 * shear_.y ); // vertices[10] = new Vector3( x2 + y2 * shear_.x, 0.0f, y2 + x2 * shear_.y ); // vertices[11] = new Vector3( x3 + y2 * shear_.x, 0.0f, y2 + x3 * shear_.y ); // vertices[12] = new Vector3( x0 + y3 * shear_.x, 0.0f, y3 + x0 * shear_.y ); // vertices[13] = new Vector3( x1 + y3 * shear_.x, 0.0f, y3 + x1 * shear_.y ); // vertices[14] = new Vector3( x2 + y3 * shear_.x, 0.0f, y3 + x2 * shear_.y ); // vertices[15] = new Vector3( x3 + y3 * shear_.x, 0.0f, y3 + x3 * shear_.y ); // break; // case Plane.ZY: // vertices[0] = new Vector3( 0.0f, y0 + x0 * shear_.y, x0 + y0 * shear_.x ); // vertices[1] = new Vector3( 0.0f, y0 + x1 * shear_.y, x1 + y0 * shear_.x ); // vertices[2] = new Vector3( 0.0f, y0 + x2 * shear_.y, x2 + y0 * shear_.x ); // vertices[3] = new Vector3( 0.0f, y0 + x3 * shear_.y, x3 + y0 * shear_.x ); // // vertices[4] = new Vector3( 0.0f, y1 + x0 * shear_.y, x0 + y1 * shear_.x ); // vertices[5] = new Vector3( 0.0f, y1 + x1 * shear_.y, x1 + y1 * shear_.x ); // vertices[6] = new Vector3( 0.0f, y1 + x2 * shear_.y, x2 + y1 * shear_.x ); // vertices[7] = new Vector3( 0.0f, y1 + x3 * shear_.y, x3 + y1 * shear_.x ); // // vertices[8] = new Vector3( 0.0f, y2 + x0 * shear_.y, x0 + y2 * shear_.x ); // vertices[9] = new Vector3( 0.0f, y2 + x1 * shear_.y, x1 + y2 * shear_.x ); // vertices[10] = new Vector3( 0.0f, y2 + x2 * shear_.y, x2 + y2 * shear_.x ); // vertices[11] = new Vector3( 0.0f, y2 + x3 * shear_.y, x3 + y2 * shear_.x ); // // vertices[12] = new Vector3( 0.0f, y3 + x0 * shear_.y, x0 + y3 * shear_.x ); // vertices[13] = new Vector3( 0.0f, y3 + x1 * shear_.y, x1 + y3 * shear_.x ); // vertices[14] = new Vector3( 0.0f, y3 + x2 * shear_.y, x2 + y3 * shear_.x ); // vertices[15] = new Vector3( 0.0f, y3 + x3 * shear_.y, x3 + y3 * shear_.x ); // break; // } // } DELME end _mesh.vertices = vertices; _mesh.bounds = GetMeshBounds(offsetX, offsetY, halfWidthScaled * 2.0f, halfHeightScaled * 2.0f); // update collider if we have UpdateBoundRect(offsetX, offsetY, halfWidthScaled * 2.0f, halfHeightScaled * 2.0f); if (collisionHelper) { collisionHelper.UpdateCollider(); } } // ======================================================== // Update UV // ======================================================== if ((updateFlags & UpdateFlags.UV) != 0) { Vector2[] uvs = new Vector2[16]; // if the sprite is in an atlas if (el != null) { float xStart = el.coords.x; float yStart = el.coords.y; float xEnd = el.coords.xMax; float yEnd = el.coords.yMax; float leftRatio = (float)guiBorder_.border.left / (float)atlas_.texture.width; float rightRatio = (float)guiBorder_.border.right / (float)atlas_.texture.width; float topRatio = (float)guiBorder_.border.top / (float)atlas_.texture.height; float bottomRatio = (float)guiBorder_.border.bottom / (float)atlas_.texture.height; float umin = xStart; float umax = xEnd; float vmin = yStart; float vmax = yEnd; float u0 = xStart; float u1 = xStart + leftRatio; float u2 = xEnd - rightRatio; float u3 = xEnd; float v0 = yEnd; float v1 = yEnd - topRatio; float v2 = yStart + bottomRatio; float v3 = yStart; // do uv clip if (clipInfo_.clipped) { umin = clipLeft >= 0.0f ? xStart + clipLeft * leftRatio : xEnd + clipLeft * rightRatio; umax = clipRight >= 0.0f ? xEnd - clipRight * rightRatio : xStart - clipRight * leftRatio; vmin = clipTop >= 0.0f ? yStart + clipTop * topRatio : yEnd + clipTop * bottomRatio; vmax = clipBottom >= 0.0f ? yEnd - clipBottom * bottomRatio : yStart - clipBottom * topRatio; u0 = Mathf.Clamp(u0, umin, umax); u1 = Mathf.Clamp(u1, umin, umax); u2 = Mathf.Clamp(u2, umin, umax); u3 = Mathf.Clamp(u3, umin, umax); v0 = Mathf.Clamp(v0, vmin, vmax); v1 = Mathf.Clamp(v1, vmin, vmax); v2 = Mathf.Clamp(v2, vmin, vmax); v3 = Mathf.Clamp(v3, vmin, vmax); } uvs[0] = new Vector2(u0, v0); uvs[1] = new Vector2(u1, v0); uvs[2] = new Vector2(u2, v0); uvs[3] = new Vector2(u3, v0); uvs[4] = new Vector2(u0, v1); uvs[5] = new Vector2(u1, v1); uvs[6] = new Vector2(u2, v1); uvs[7] = new Vector2(u3, v1); uvs[8] = new Vector2(u0, v2); uvs[9] = new Vector2(u1, v2); uvs[10] = new Vector2(u2, v2); uvs[11] = new Vector2(u3, v2); uvs[12] = new Vector2(u0, v3); uvs[13] = new Vector2(u1, v3); uvs[14] = new Vector2(u2, v3); uvs[15] = new Vector2(u3, v3); } else { float xStart = 0.0f; float yStart = 0.0f; float xEnd = 1.0f; float yEnd = 1.0f; Texture texture = renderer.sharedMaterial.mainTexture; float leftRatio = (float)guiBorder_.border.left / (float)texture.width; float rightRatio = (float)guiBorder_.border.right / (float)texture.width; float topRatio = (float)guiBorder_.border.top / (float)texture.height; float bottomRatio = (float)guiBorder_.border.bottom / (float)texture.height; float umin = xStart; float umax = xEnd; float vmin = yStart; float vmax = yEnd; float u0 = xStart; float u1 = xStart + leftRatio; float u2 = xEnd - rightRatio; float u3 = xEnd; float v0 = yEnd; float v1 = yEnd - topRatio; float v2 = yStart + bottomRatio; float v3 = yStart; // do uv clip if (clipInfo_.clipped) { umin = clipLeft >= 0.0f ? xStart + clipLeft * leftRatio : xEnd + clipLeft * rightRatio; umax = clipRight >= 0.0f ? xEnd - clipRight * rightRatio : xStart - clipRight * leftRatio; vmin = clipTop >= 0.0f ? yStart + clipTop * topRatio : yEnd + clipTop * bottomRatio; vmax = clipBottom >= 0.0f ? yEnd - clipBottom * bottomRatio : yStart - clipBottom * topRatio; u0 = Mathf.Clamp(u0, umin, umax); u1 = Mathf.Clamp(u1, umin, umax); u2 = Mathf.Clamp(u2, umin, umax); u3 = Mathf.Clamp(u3, umin, umax); v0 = Mathf.Clamp(v0, vmin, vmax); v1 = Mathf.Clamp(v1, vmin, vmax); v2 = Mathf.Clamp(v2, vmin, vmax); v3 = Mathf.Clamp(v3, vmin, vmax); } uvs[0] = new Vector2(u0, v0); uvs[1] = new Vector2(u1, v0); uvs[2] = new Vector2(u2, v0); uvs[3] = new Vector2(u3, v0); uvs[4] = new Vector2(u0, v1); uvs[5] = new Vector2(u1, v1); uvs[6] = new Vector2(u2, v1); uvs[7] = new Vector2(u3, v1); uvs[8] = new Vector2(u0, v2); uvs[9] = new Vector2(u1, v2); uvs[10] = new Vector2(u2, v2); uvs[11] = new Vector2(u3, v2); uvs[12] = new Vector2(u0, v3); uvs[13] = new Vector2(u1, v3); uvs[14] = new Vector2(u2, v3); uvs[15] = new Vector2(u3, v3); } _mesh.uv = uvs; } // ======================================================== // Update Color // ======================================================== if ((updateFlags & UpdateFlags.Color) != 0) { Color[] colors = new Color[16]; for (int i = 0; i < 16; ++i) { colors[i] = color_; } _mesh.colors = colors; } // ======================================================== // Update Index // ======================================================== if ((updateFlags & UpdateFlags.Index) != 0) { int[] indices = new int[6 * 9]; for (int i = 0; i < 3; ++i) { int vid = 4 * i; for (int j = 0; j < 3; ++j) { int vert_id = vid + j; int idx_id = 6 * (i * 3 + j); indices[idx_id + 0] = vert_id + 0; indices[idx_id + 1] = vert_id + 1; indices[idx_id + 2] = vert_id + 4; indices[idx_id + 3] = vert_id + 4; indices[idx_id + 4] = vert_id + 1; indices[idx_id + 5] = vert_id + 5; } } _mesh.triangles = indices; } // NOTE: though we set updateFlags to None at exPlane::LateUpdate, // the Editor still need this or it will caused editor keep dirty updateFlags = UpdateFlags.None; }
// ------------------------------------------------------------------ /// \param _mesh the mesh to update /// /// Update the _mesh depends on the exPlane.updateFlags // ------------------------------------------------------------------ public void UpdateMesh(Mesh _mesh) { exAtlas.Element el = null; if (useAtlas) { el = atlas_.elements[index_]; } // ======================================================== // Update Vertex // ======================================================== if ((updateFlags & UpdateFlags.Vertex) != 0) { Vector2 finalScale = new Vector2(scale_.x * ppfScale_.x, scale_.y * ppfScale_.y); // init float halfWidthScaled = width_ * finalScale.x * 0.5f; float halfHeightScaled = height_ * finalScale.y * 0.5f; float offsetX = 0.0f; float offsetY = 0.0f; Vector3[] vertices = new Vector3[4]; Vector3[] normals = new Vector3[4]; // calculate anchor offset if (useTextureOffset_) { // get original width and height float originalWidth = 0.0f; float originalHeight = 0.0f; Rect trimRect = new Rect(0, 0, 1, 1); if (el != null) { originalWidth = el.originalWidth * finalScale.x; originalHeight = el.originalHeight * finalScale.y; trimRect = new Rect(el.trimRect.x * finalScale.x, el.trimRect.y * finalScale.y, el.trimRect.width * finalScale.x, el.trimRect.height * finalScale.y); } else { if (GetComponent <Renderer>().sharedMaterial != null) { Texture texture = GetComponent <Renderer>().sharedMaterial.mainTexture; originalWidth = texture.width * finalScale.x; originalHeight = texture.height * finalScale.y; trimRect = new Rect(trimUV.x * originalWidth, (1.0f - trimUV.height - trimUV.y) * originalHeight, trimUV.width * originalWidth, trimUV.height * originalHeight); } } switch (anchor_) { // case Anchor.TopLeft: offsetX = -halfWidthScaled - trimRect.x; offsetY = -halfHeightScaled - trimRect.y; break; case Anchor.TopCenter: offsetX = (originalWidth - trimRect.width) * 0.5f - trimRect.x; offsetY = -halfHeightScaled - trimRect.y; break; case Anchor.TopRight: offsetX = halfWidthScaled + originalWidth - trimRect.xMax; offsetY = -halfHeightScaled - trimRect.y; break; // case Anchor.MidLeft: offsetX = -halfWidthScaled - trimRect.x; offsetY = (originalHeight - trimRect.height) * 0.5f - trimRect.y; break; case Anchor.MidCenter: offsetX = (originalWidth - trimRect.width) * 0.5f - trimRect.x; offsetY = (originalHeight - trimRect.height) * 0.5f - trimRect.y; break; case Anchor.MidRight: offsetX = halfWidthScaled + originalWidth - trimRect.xMax; offsetY = (originalHeight - trimRect.height) * 0.5f - trimRect.y; break; // case Anchor.BotLeft: offsetX = -halfWidthScaled - trimRect.x; offsetY = halfHeightScaled + originalHeight - trimRect.yMax; break; case Anchor.BotCenter: offsetX = (originalWidth - trimRect.width) * 0.5f - trimRect.x; offsetY = halfHeightScaled + originalHeight - trimRect.yMax; break; case Anchor.BotRight: offsetX = halfWidthScaled + originalWidth - trimRect.xMax; offsetY = halfHeightScaled + originalHeight - trimRect.yMax; break; default: offsetX = (originalWidth - trimRect.width) * 0.5f - trimRect.x; offsetY = (originalHeight - trimRect.height) * 0.5f - trimRect.y; break; } } else { switch (anchor_) { case Anchor.TopLeft: offsetX = -halfWidthScaled; offsetY = -halfHeightScaled; break; case Anchor.TopCenter: offsetX = 0.0f; offsetY = -halfHeightScaled; break; case Anchor.TopRight: offsetX = halfWidthScaled; offsetY = -halfHeightScaled; break; case Anchor.MidLeft: offsetX = -halfWidthScaled; offsetY = 0.0f; break; case Anchor.MidCenter: offsetX = 0.0f; offsetY = 0.0f; break; case Anchor.MidRight: offsetX = halfWidthScaled; offsetY = 0.0f; break; case Anchor.BotLeft: offsetX = -halfWidthScaled; offsetY = halfHeightScaled; break; case Anchor.BotCenter: offsetX = 0.0f; offsetY = halfHeightScaled; break; case Anchor.BotRight: offsetX = halfWidthScaled; offsetY = halfHeightScaled; break; default: offsetX = 0.0f; offsetY = 0.0f; break; } } offsetX -= offset_.x; offsetY += offset_.y; float minX = 9999.0f; float minY = 9999.0f; float maxX = -9999.0f; float maxY = -9999.0f; // build vertices & normals for (int r = 0; r < 2; ++r) { for (int c = 0; c < 2; ++c) { int i = r * 2 + c; float x, y; CalculateVertex(out x, out y, width_ * finalScale.x, height_ * finalScale.y, c, r, offsetX, offsetY); vertices[i] = new Vector3(x, y, 0.0f); normals[i] = new Vector3(0.0f, 0.0f, -1.0f); if (x < minX) { minX = x; } else if (x > maxX) { maxX = x; } if (y < minY) { minY = y; } else if (y > maxY) { maxY = y; } } } float shearScaleWidth = maxX - minX; float shearScaleHeight = maxY - minY; _mesh.vertices = vertices; _mesh.normals = normals; _mesh.bounds = GetMeshBounds(offsetX, offsetY, shearScaleWidth, shearScaleHeight); // update collider if we have UpdateBoundRect(offsetX, offsetY, shearScaleWidth, shearScaleHeight); if (collisionHelper) { collisionHelper.UpdateCollider(); } // #if UNITY_EDITOR // _mesh.RecalculateBounds(); // #endif } // ======================================================== // Update UV // ======================================================== if ((updateFlags & UpdateFlags.UV) != 0) { Vector2[] uvs = new Vector2[4]; // if the sprite is in an atlas if (el != null) { float xStart = el.coords.x; float yStart = el.coords.y; float xEnd = el.coords.xMax; float yEnd = el.coords.yMax; if (el.rotated) { uvs[0] = new Vector2(xEnd, yEnd); uvs[1] = new Vector2(xEnd, yStart); uvs[2] = new Vector2(xStart, yEnd); uvs[3] = new Vector2(xStart, yStart); } else { uvs[0] = new Vector2(xStart, yEnd); uvs[1] = new Vector2(xEnd, yEnd); uvs[2] = new Vector2(xStart, yStart); uvs[3] = new Vector2(xEnd, yStart); } } else { float xStart = trimUV.x; float yStart = trimUV.y; float xEnd = trimUV.xMax; float yEnd = trimUV.yMax; uvs[0] = new Vector2(xStart, yEnd); uvs[1] = new Vector2(xEnd, yEnd); uvs[2] = new Vector2(xStart, yStart); uvs[3] = new Vector2(xEnd, yStart); } _mesh.uv = uvs; } // ======================================================== // Update Color // ======================================================== if ((updateFlags & UpdateFlags.Color) != 0) { Color[] colors = new Color[4]; for (int i = 0; i < 4; ++i) { colors[i] = color_; } _mesh.colors = colors; } // ======================================================== // Update Index // ======================================================== if ((updateFlags & UpdateFlags.Index) != 0) { int[] indices = new int[6]; indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 2; indices[4] = 1; indices[5] = 3; _mesh.triangles = indices; } // NOTE: though we set updateFlags to None at exPlane::LateUpdate, // the Editor still need this or it will caused editor keep dirty updateFlags = UpdateFlags.None; }
// ------------------------------------------------------------------ /// \param _atlasInfo the atlas info /// \param _noImport if true, ex2D will not import the texture to fit for atlas /// build the atlas info to atlas // ------------------------------------------------------------------ public static void Build( exAtlasInfo _atlasInfo, bool _noImport = false ) { exAtlas atlas = _atlasInfo.atlas; Texture2D texture = _atlasInfo.texture; Material material = _atlasInfo.material; // check if the atlas info is valid for build if ( atlas == null ) { Debug.LogError("Failed to build atlas info " + _atlasInfo.name + ", the atlas is missing!"); return; } if ( texture == null ) { Debug.LogError("Failed to build atlas info " + _atlasInfo.name + ", the texture is missing!"); return; } if ( material == null ) { Debug.LogError("Failed to build atlas info " + _atlasInfo.name + ", the material is missing!"); return; } // if ( _atlasInfo.needLayout ) { _atlasInfo.LayoutElements(); _atlasInfo.needLayout = false; } // create temp texture Color32 buildColor = new Color ( 0.0f, 0.0f, 0.0f, 0.0f ); if ( _atlasInfo.useBuildColor ) buildColor = new Color ( _atlasInfo.buildColor.r, _atlasInfo.buildColor.g, _atlasInfo.buildColor.b, 0.0f ); string path = AssetDatabase.GetAssetPath(texture); TextureImporter importer = TextureImporter.GetAtPath(path) as TextureImporter; // TextureImporterSettings textureImporterSettings = new TextureImporterSettings(); // importer.ReadTextureSettings(textureImporterSettings); // textureImporterSettings.readable = true; // importer.SetTextureSettings(textureImporterSettings); importer.wrapMode = TextureWrapMode.Clamp; importer.isReadable = true; AssetDatabase.ImportAsset( path ); Color32[] colors = new Color32[_atlasInfo.width*_atlasInfo.height]; for ( int i = 0; i < _atlasInfo.width * _atlasInfo.height; ++i ) colors[i] = buildColor; texture.SetPixels32( colors ); try { EditorUtility.DisplayProgressBar( "Building Atlas " + _atlasInfo.name, "Building Atlas...", 0.1f ); // build atlas texture _atlasInfo.elements.Sort( exAtlasInfo.CompareByName ); FillAtlasTexture ( texture, _atlasInfo, _noImport ); EditorUtility.DisplayProgressBar( "Building Atlas " + _atlasInfo.name, "Import Atlas", 0.9f ); // write to disk byte[] pngData = texture.EncodeToPNG(); if (pngData != null) File.WriteAllBytes(path, pngData); // now we finish atlas texture filling, we should turn off Read/Write settings, that will save memory a lot! TextureImporter importSettings = TextureImporter.GetAtPath(path) as TextureImporter; importSettings.wrapMode = TextureWrapMode.Clamp; importSettings.isReadable = _atlasInfo.readable; AssetDatabase.ImportAsset( path ); // atlas.elements = new exAtlas.Element[_atlasInfo.elements.Count]; for ( int i = 0; i < _atlasInfo.elements.Count; ++i ) { exAtlasInfo.Element el = _atlasInfo.elements[i]; exAtlas.Element el2 = new exAtlas.Element (); int coord_x = el.coord[0]; int coord_y = el.atlasInfo.height - el.coord[1] - (int)el.Height(); float xStart = (float)coord_x / (float)el.atlasInfo.width; float yStart = (float)coord_y / (float)el.atlasInfo.height; float xEnd = (float)(coord_x + el.Width()) / (float)el.atlasInfo.width; float yEnd = (float)(coord_y + el.Height()) / (float)el.atlasInfo.height; el2.name = el.texture.name; el2.coords = new Rect ( xStart, yStart, xEnd - xStart, yEnd - yStart ); el2.rotated = el.rotated; el2.originalWidth = el.texture.width; el2.originalHeight = el.texture.height; el2.trimRect = el.trimRect; atlas.elements[i] = el2; // update the index in exAtlasDB if ( el.isFontElement == false ) { exAtlasDB.UpdateElementInfo( el, i ); } } atlas.texture = texture; atlas.material = material; EditorUtility.SetDirty(atlas); EditorUtility.ClearProgressBar(); } catch ( System.Exception ) { EditorUtility.ClearProgressBar(); throw; } // save the needRebuild setting _atlasInfo.needRebuild = false; EditorUtility.SetDirty(_atlasInfo); }