// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ protected override void DoInspectorGUI() { base.DoInspectorGUI(); // depth EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(depthProp, new GUIContent("Depth")); if (EditorGUI.EndChangeCheck()) { foreach (Object obj in serializedObject.targetObjects) { exLayeredSprite sp = obj as exLayeredSprite; if (sp) { sp.depth = depthProp.floatValue; EditorUtility.SetDirty(sp); } } } EditorGUILayout.Space(); }
public void CheckDuplicated (exLayeredSprite _sprite) { #if UNITY_EDITOR if (ordered_ == false) { return; } Material mat = _sprite.material; for (int i = meshList.Count - 1; i >= 0; --i) { exMesh mesh = meshList[i]; if (ReferenceEquals(mesh.material, mat) && mesh != null) { for (int j = 0, jMax = mesh.spriteList.Count; j < jMax; ++j) { if (_sprite.spriteIdInLayer == mesh.spriteList[j].spriteIdInLayer) { _sprite.spriteIdInLayer = -1; //duplicated break; } } } } #endif }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public static void RegisterMaterialDirty (exLayeredSprite _sprite) { spriteNeedsToSetMaterialDirty = _sprite; }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ internal void RefreshSpriteMaterial (exLayeredSprite _sprite) { // 先更新所有depth值,如果遍历到_sprite,则更新的同时SetMaterialDirty UpdateSpriteWhileRecreating.RegisterMaterialDirty(_sprite); UpdateAllSpritesDepth(); if (UpdateSpriteWhileRecreating.Clear() == false) { // 假如更新depth时没遍历到_sprite,则手动更新 int meshIndex = IndexOfMesh(_sprite); if (meshIndex != -1) { //Debug.Log("before remove"); //meshList[meshIndex].OutputDebugInfo(true); RemoveFromMesh(_sprite, meshList[meshIndex]); //Debug.Log("after remove"); //meshList[meshIndex].OutputDebugInfo(true); } (_sprite as IFriendOfLayer).SetMaterialDirty(); var mesh = GetMeshToAdd(_sprite); AddToMesh(_sprite, mesh); //Debug.Log("after add"); //mesh.OutputDebugInfo(true); } }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public static void RegisterNewBufferSize (exLayeredSprite _sprite, int _vertexCount, int _indexCount) { spriteNeedsToSetBufferSize = _sprite; newVertexCount = _vertexCount; newIndexCount = _indexCount; }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ internal void FastHideSprite (exLayeredSprite _sprite) { _sprite.transparent = true; UpdateNowInEditMode(); }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ internal void HideSprite (exLayeredSprite _sprite) { exDebug.Assert(false, "必须开启enableFastShowHide,因为GetMeshToAdd要获取mesh中最先和最后渲染的sprite,要保证sprite都在sortedSpriteList中"); if (_sprite.isInIndexBuffer) { int meshIndex = IndexOfMesh(_sprite); if (meshIndex != -1) { RemoveIndices(meshList[meshIndex], _sprite); exDebug.Assert(_sprite.indexBufferIndex == -1); UpdateNowInEditMode(); } } }
// ------------------------------------------------------------------ /// \param _recursively Also remove all sprites in the hierarchy // ------------------------------------------------------------------ public void Remove (exLayeredSprite _sprite, bool _recursively = true) { if (_recursively) { Remove(_sprite.gameObject, _recursively); } else { if (_sprite.layer != this) { Debug.LogWarning ("Sprite not in this layer."); return; } int meshIndex = IndexOfMesh (_sprite); if (meshIndex != -1) { RemoveFromMesh (_sprite, meshList [meshIndex]); (_sprite as IFriendOfLayer).DoSetLayer (null); } else { (_sprite as IFriendOfLayer).ResetLayerProperties (); //if mesh has been destroyed, just reset sprite } if (_sprite.spriteIdInLayer == nextSpriteUniqueId - 1 && nextSpriteUniqueId > 0) { --nextSpriteUniqueId; } _sprite.spriteIdInLayer = -1; } }
// ------------------------------------------------------------------ /// 在保证渲染次序的前提下,获得可供插入的mesh,必要的话会进行mesh的拆分和创建操作。 /// 这个算法保证mesh不产生零散的碎片,效率应该还有优化的余地。 // ------------------------------------------------------------------ private exMesh GetMeshToAdd (exLayeredSprite _sprite) { Material mat = _sprite.material; int maxVertexCount = (layerType_ == exLayerType.Dynamic) ? maxDynamicMeshVertex : exMesh.MAX_VERTEX_COUNT; maxVertexCount -= _sprite.vertexCount; exMesh lastMesh = null; // TODO: 如果sprite的vertex count大于maxVertexCount for (int i = meshList.Count - 1; i >= 0; --i) { exMesh mesh = meshList[i]; if (mesh == null) continue; exDebug.Assert(exLayeredSprite.enableFastShowHide); // 要获取mesh中最先和最后渲染的sprite,要保证sprite都在sortedSpriteList中 if (mesh.sortedSpriteList.Count == 0) continue; // 跳过空的mesh,尽量把sprite合并到已有的mesh里面 exLayeredSprite top = mesh.sortedSpriteList[mesh.sortedSpriteList.Count - 1]; exLayeredSprite bot = mesh.sortedSpriteList[0]; bool canSkipMesh = ordered_ == false && _sprite <= bot; // 如果sprite的depth和mesh里所有的depth都相等,则可放到当前mesh下 bool aboveTopSprite = _sprite >= top; if (aboveTopSprite) { // 在这个mesh之上层 if (ReferenceEquals(mesh.material, mat) && mesh.vertices.Count <= maxVertexCount) { return mesh; // bingo } if (canSkipMesh) { continue; // 不符合条件,跳到下一个mesh去判断,有可能就不用创建新mesh } else { bool canAppendToLastMesh = !ReferenceEquals(lastMesh, null) && ReferenceEquals(lastMesh.material, mat) && lastMesh.vertices.Count <= maxVertexCount; if (canAppendToLastMesh) return lastMesh; // 贴到上一个mesh屁股下 else return GetNewMesh(mat, i + 1); // 不符合条件,在mesh上层创建一个新mesh } } bool aboveBottomSprite = _sprite >= bot; if (aboveBottomSprite) { // 在这个mesh的depth内,如果bot == top,则不会运行到这里 if (ReferenceEquals(mesh.material, mat)) { if (mesh.vertices.Count <= maxVertexCount) { return mesh; // bingo } if (canSkipMesh) continue; // 不符合条件,跳到下一个mesh去判断,有可能就不用创建新mesh else // 材质相同但mesh过大,把mesh的上面的sprite分出去,然后用新加的sprite依次填满空出来的格子 return GetShiftedMesh(i, _sprite, maxVertexCount); } else { if (canSkipMesh) { continue; // 不符合条件,跳到下一个mesh去判断,有可能就不用创建新mesh } else { // 两个相同材质的sprite中间插入了另一个材质的sprite,则需要将上下两个sprite拆分到两个不同的mesh // 然后将上面的sprite往上移动,直到该mesh只包含下面的sprite,然后插入其它材质的mesh SplitMesh(i, _sprite, maxVertexCount); return GetNewMesh(mat, i + 1); } } } lastMesh = mesh; } if (meshList.Count > 0) { exMesh bottomMesh = meshList[0]; if (ReferenceEquals(bottomMesh.material, mat) && bottomMesh.vertices.Count <= maxVertexCount) { // 插入到最下面一个mesh return bottomMesh; } // 在最下面创建一个新mesh exMesh newMesh = GetNewMesh(mat, 0); if (ReferenceEquals(bottomMesh.material, mat)) { ShiftSpritesDown(0, maxVertexCount, maxVertexCount); // 向下把mesh都填满 } return newMesh; } return GetNewMesh(mat, 0); }
// ------------------------------------------------------------------ /// Split the mesh /// \param _meshIndex The index of the mesh to split /// \param _seperatorSprite 深度小于等于它的sprite将会被分隔到新创建的下层的mesh中 /// \param _maxVertexCount The max vertex count of meshes in layer // ------------------------------------------------------------------ private void SplitMesh (int _meshIndex, exLayeredSprite _seperatorSprite, int _maxVertexCount) { int t; int belowVertexCount = GetBelowVertexCountInMesh(_meshIndex, _seperatorSprite, _maxVertexCount, out t); ShiftSpritesUp(_meshIndex, belowVertexCount, _maxVertexCount); // 上移 }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public static bool MeshMaybeChange (exLayeredSprite _sprite) { return ReferenceEquals(_sprite, spriteNeedsToSetBufferSize) || ReferenceEquals(_sprite, spriteNeedsToSetMaterialDirty); }
// ------------------------------------------------------------------ /// Shift sprites to the above mesh to make it has space to insert new sprite /// \param _meshIndex The index of the mesh to insert /// \param _sprite The sprite to insert /// \param _maxVertexCount The max vertex count of meshes in layer /// \return The mesh to insert // ------------------------------------------------------------------ private exMesh GetShiftedMesh (int _meshIndex, exLayeredSprite _sprite, int _maxVertexCount) { exMesh mesh = meshList[_meshIndex]; int newSpriteVertexCount = _sprite.vertexCount; int aboveSpriteIndex; GetBelowVertexCountInMesh(_meshIndex, _sprite, _maxVertexCount, out aboveSpriteIndex); int belowVertexCount = mesh.vertices.Count; for (int i = mesh.sortedSpriteList.Count - 1; i >= aboveSpriteIndex; --i) { exLayeredSprite aboveSprite = mesh.sortedSpriteList[i]; belowVertexCount -= aboveSprite.vertexCount; if (belowVertexCount + newSpriteVertexCount <= _maxVertexCount) { ShiftSpritesUp(_meshIndex, belowVertexCount, _maxVertexCount); // 上移 return mesh; } } // 完全不能容纳,则把新的sprite和在它上面的sprite都再送到上一个mesh中 if (_meshIndex + 1 < meshList.Count) { int aboveVertexCount = mesh.vertices.Count - belowVertexCount; int aboveMeshVertexCount = _maxVertexCount - aboveVertexCount - newSpriteVertexCount; ShiftSpritesUp(_meshIndex + 1, aboveMeshVertexCount, _maxVertexCount); // 空出上一个mesh ShiftSpritesUp(_meshIndex, belowVertexCount, _maxVertexCount); // 把需要渲染在上面的sprite移到上面的mesh return meshList[_meshIndex + 1]; } return mesh; }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ private int GetBelowVertexCountInMesh (int _meshIndex, exLayeredSprite _sprite, int _maxVertexCount, out int _aboveSpriteIndex) { exMesh mesh = meshList[_meshIndex]; _aboveSpriteIndex = mesh.sortedSpriteList.BinarySearch(_sprite); if (_aboveSpriteIndex < 0) { _aboveSpriteIndex = ~_aboveSpriteIndex; exDebug.Assert(0 < _aboveSpriteIndex && _aboveSpriteIndex <= mesh.sortedSpriteList.Count - 1, "no need to shift the mesh"); } else { exDebug.Assert(0 < _aboveSpriteIndex && _aboveSpriteIndex < mesh.sortedSpriteList.Count - 1, "no need to shift the mesh", this); ++_aboveSpriteIndex; // just insert above same depth sprite } if (_aboveSpriteIndex <= mesh.sortedSpriteList.Count) { int belowVertexCount = 0; for (int i = 0; i < _aboveSpriteIndex; ++i) { belowVertexCount += mesh.sortedSpriteList[i].vertexCount; } return belowVertexCount; } return mesh.vertices.Count; }
Rect MapBoundingRect( Rect _rect, exLayeredSprite _node ) { exLayeredSprite layeredSprite = _node as exLayeredSprite; Vector2 screenPos = Vector2.zero; if ( layeredSprite ) { Rect boundingRect = layeredSprite.GetWorldAABoundingRect(); screenPos = SceneField_WorldToScreen ( _rect, boundingRect.center ); boundingRect = new Rect ( screenPos.x - boundingRect.width * scale / 2.0f, screenPos.y - boundingRect.height * scale / 2.0f, boundingRect.width * scale, boundingRect.height * scale ); boundingRect = exGeometryUtility.Rect_FloorToInt(boundingRect); return boundingRect; } screenPos = SceneField_WorldToScreen ( _rect, _node.transform.position ); return new Rect ( screenPos.x * scale, screenPos.y * scale, 1.0f * scale, 1.0f * scale ); }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public static bool Clear () { bool processed = (spriteNeedsToSetBufferSize == null && spriteNeedsToSetMaterialDirty == null); spriteNeedsToSetBufferSize = null; spriteNeedsToSetMaterialDirty = null; return processed; }
// ------------------------------------------------------------------ /// Add an exLayeredSprite to this layer. /// If sprite is disabled, it will keep invisible until you enable it. /// \param _recursively Also add all sprites in the hierarchy /// NOTE: You can also use exLayeredSprite.SetLayer for convenience. // ------------------------------------------------------------------ public void Add (exLayeredSprite _sprite, bool _recursively = true) { if (_recursively == true) { exLayer oldLayer = _sprite.layer; if (ReferenceEquals (oldLayer, this)) { return; } if (oldLayer != null) { oldLayer.Remove (_sprite, true); } exLayeredSprite[] spritesToAdd = _sprite.GetComponentsInChildren<exLayeredSprite> (true); for (int spriteIndex = 0; spriteIndex < spritesToAdd.Length; ++spriteIndex) { DoAddSprite (spritesToAdd [spriteIndex], true); } if (_sprite.cachedTransform.IsChildOf (cachedTransform) == false) { _sprite.cachedTransform.parent = cachedTransform_; } UpdateNowInEditMode (); } else { DoAddSprite (_sprite, true); } }
// ------------------------------------------------------------------ /// Do add the sprite to the layer /// \param _newSprite 如果为true,则将sprite渲染到其它相同depth的sprite上面 // ------------------------------------------------------------------ private void DoAddSprite (exLayeredSprite _sprite, bool _newSprite) { #if EX_DEBUG || UNITY_EDITOR if (ReferenceEquals(_sprite.layer, this)) { Debug.LogError("Sprite has been added to layer " + gameObject.name, _sprite); return; } if (_sprite.layer != null) { Debug.LogError("Sprite should remove from old layer before add to new one"); return; } #endif Material mat = _sprite.material; if (mat == null) { #if EX_DEBUG Debug.LogWarning("Ignore null material sprite", _sprite); #endif return; } (_sprite as IFriendOfLayer).DoSetLayer(this); // set sprite id CheckDuplicated(_sprite); if (ordered_ && _newSprite || _sprite.spriteIdInLayer == -1) { _sprite.spriteIdInLayer = nextSpriteUniqueId; ++nextSpriteUniqueId; } else { nextSpriteUniqueId = Mathf.Max(_sprite.spriteIdInLayer + 1, nextSpriteUniqueId); } // caculate depth (_sprite as IFriendOfLayer).globalDepth = GetParentGlobalDepth(_sprite.gameObject) + _sprite.depth; // find available mesh exMesh mesh = GetMeshToAdd(_sprite); exDebug.Assert(mesh.vertices.Count + _sprite.vertexCount <= (layerType_ == exLayerType.Dynamic ? maxDynamicMeshVertex : exMesh.MAX_VERTEX_COUNT), string.Format("Invalid mesh vertex count : {0}", (mesh.vertices.Count + _sprite.vertexCount))); AddToMesh(_sprite, mesh); }
// ------------------------------------------------------------------ /// Show an exLayeredSprite /// NOTE: This function should only be called by exLayeredSprite // ------------------------------------------------------------------ internal void ShowSprite (exLayeredSprite _sprite) { if (_sprite.isInIndexBuffer == false) { int meshIndex = IndexOfMesh(_sprite); if (meshIndex != -1) { AddIndices(meshList[meshIndex], _sprite); UpdateNowInEditMode(); } } else { _sprite.transparent = false; UpdateNowInEditMode(); } }
// ------------------------------------------------------------------ /// Add an exLayeredSprite to the mesh. // ------------------------------------------------------------------ private void AddToMesh (exLayeredSprite _sprite, exMesh _mesh) { exDebug.Assert(_mesh.spriteList.Contains(_sprite) == false, "Can't add duplicated sprite"); _sprite.updateFlags = exUpdateFlags.None; _sprite.spriteIndexInMesh = _mesh.spriteList.Count; _mesh.spriteList.Add(_sprite); _sprite.FillBuffers(_mesh.vertices, _mesh.uvs, _mesh.colors32); if (exLayeredSprite.enableFastShowHide) { AddIndices(_mesh, _sprite); _sprite.transparent = !_sprite.visible; } else if (_sprite.visible) { AddIndices(_mesh, _sprite); } exDebug.Assert(_mesh.vertices.Count == _mesh.uvs.Count, "uvs array needs to be the same size as the vertices array"); exDebug.Assert(_mesh.vertices.Count == _mesh.colors32.Count, "colors32 array needs to be the same size as the vertices array"); }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ internal void FastShowSprite (exLayeredSprite _sprite) { if (_sprite.isInIndexBuffer == false) { ShowSprite (_sprite); } else { _sprite.transparent = false; UpdateNowInEditMode(); } }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ private void RemoveFromMesh (exLayeredSprite _sprite, exMesh _mesh) { _mesh.spriteList.RemoveAt(_sprite.spriteIndexInMesh); int vertexCount = _sprite.vertexCount; for (int i = _sprite.spriteIndexInMesh; i < _mesh.spriteList.Count; ++i) { exLayeredSprite sprite = _mesh.spriteList[i]; // update sprite and vertic index after removed sprite sprite.spriteIndexInMesh = i; sprite.vertexBufferIndex -= vertexCount; // update indices to make them match new vertic index if (sprite.isInIndexBuffer) { int indexEnd = sprite.indexBufferIndex + sprite.indexCount; for (int index = sprite.indexBufferIndex; index < indexEnd; ++index) { //if (index >= _mesh.indices.Count) { // Debug.Log(string.Format("[RemoveFromMesh|exLayer] index: {1} _mesh.indices.Count: {0}", _mesh.indices.Count, index)); //} if (_mesh.indices.buffer[index] > 0) { // only shift if inited index in case of negative index value _mesh.indices.buffer[index] -= vertexCount; #if EX_DEBUG if (_mesh.indices.buffer[index] < 0 && (sprite.updateFlags & exUpdateFlags.Index) == 0) { Debug.LogError(string.Format("Failed setting triangles. Some indices are referencing out of bounds vertices. " + "removing sprite: {0}, error sprite: {2} mesh: {1}", _sprite.gameObject.name, _mesh.gameObject.name, sprite), sprite); sprite.OutputDebugInfo(); } #endif } } } } _mesh.updateFlags |= exUpdateFlags.VertexAndIndex; // update vertices _mesh.vertices.RemoveRange(_sprite.vertexBufferIndex, vertexCount); _mesh.colors32.RemoveRange(_sprite.vertexBufferIndex, vertexCount); _mesh.uvs.RemoveRange(_sprite.vertexBufferIndex, vertexCount); #if LAZY_UPDATE_BUFFER_TAIL bool removeLastSprite = (_sprite.spriteIndexInMesh == _mesh.spriteList.Count); if (!removeLastSprite) { _mesh.updateFlags |= (exUpdateFlags.Color | exUpdateFlags.UV | exUpdateFlags.Normal); } #else _mesh.updateFlags |= (UpdateFlags.Color | UpdateFlags.UV | UpdateFlags.Normal); #endif if (_sprite.isInIndexBuffer) { RemoveIndices(_mesh, _sprite); } exDebug.Assert(_sprite.indexBufferIndex == -1); exDebug.Assert(_mesh.vertices.Count == _mesh.uvs.Count, "uvs array needs to be the same size as the vertices array"); exDebug.Assert(_mesh.vertices.Count == _mesh.colors32.Count, "colors32 array needs to be the same size as the vertices array"); }
//// ------------------------------------------------------------------ //// Desc: //// ------------------------------------------------------------------ //private void SetDepthDirtyFlag (exLayeredSprite _sprite, bool _dirty) { // if (_dirty) { // _sprite.updateFlags |= exUpdateFlags.SelfDepth; // } // else { // _sprite.updateFlags &= ~exUpdateFlags.SelfDepth; // } //} // ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ private void UpdateSpriteDepth (exLayeredSprite _sprite, float _parentGlobalDepth) { // caculate global depth float newGlobalDepth = _parentGlobalDepth + _sprite.depth; if ((_sprite as IFriendOfLayer).globalDepth == newGlobalDepth) { //Debug.Log("[UpdateSpriteDepth|exLayer] return"); return; } (_sprite as IFriendOfLayer).globalDepth = newGlobalDepth; if (_sprite.isInIndexBuffer == false) { return; } // update mesh int oldMeshIndex = IndexOfMesh (_sprite); exDebug.Assert(oldMeshIndex != -1); exMesh mesh = meshList[oldMeshIndex]; bool meshMaybeChange = UpdateSpriteWhileRecreating.MeshMaybeChange(_sprite); if (meshMaybeChange || IsRenderOrderChangedAmongMeshes(_sprite, oldMeshIndex)) { //Debug.Log(string.Format("[UpdateSpriteDepth|exLayer] mesh: {0}", mesh)); RemoveFromMesh(_sprite, mesh); // 这里需要保证depth改变后也能正常remove UpdateSpriteWhileRecreating.TryUpdate(_sprite); AddToMesh(_sprite, GetMeshToAdd(_sprite)); } else { // 这里不对查找进行优化,如果有必要可再加 //int oldSortedSpriteIndex = mesh.sortedSpriteList.BinarySearch(_sprite); //exDebug.Assert(oldSortedSpriteIndex >= 0); // 用原来的depth进行搜索,如果搜索不到,说明sortedSpriteList的排序是错的,这可能是因为值被animtion误改了。 int oldSortedSpriteIndex = mesh.sortedSpriteList.IndexOf(_sprite); exDebug.Assert(oldSortedSpriteIndex >= 0); // if (IsRenderOrderChangedInMesh(_sprite, oldMeshIndex, oldSortedSpriteIndex)) { //Debug.Log("[UpdateSpriteDepth|exLayer] changed"); RemoveFromMesh(_sprite, mesh); // 这里需要保证depth改变后也能正常remove AddToMesh(_sprite, mesh); } //else { // Debug.Log("[UpdateSpriteDepth|exLayer] not changed"); //} } }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ private void AddIndices (exMesh _mesh, exLayeredSprite _sprite) { exDebug.Assert(!_sprite.isInIndexBuffer); if (!_sprite.isInIndexBuffer) { int sortedSpriteIndex; if (_mesh.sortedSpriteList.Count > 0) { if (ordered_ == false && _sprite >= _mesh.sortedSpriteList[_mesh.sortedSpriteList.Count - 1]) { // check whether we can just append it sortedSpriteIndex = _mesh.sortedSpriteList.Count; } else { sortedSpriteIndex = _mesh.sortedSpriteList.BinarySearch(_sprite); exDebug.Assert(ordered_ == false || sortedSpriteIndex < 0, "sprite实现的比较方法决定了这种情况下不可能找到等同的排序"); } if (sortedSpriteIndex < 0) { sortedSpriteIndex = ~sortedSpriteIndex; } if (sortedSpriteIndex >= _mesh.sortedSpriteList.Count) { // this sprite's depth is biggest _sprite.indexBufferIndex = _mesh.indices.Count; #if EX_DEBUG exLayeredSprite lastSprite = _mesh.sortedSpriteList[_mesh.sortedSpriteList.Count - 1]; exDebug.Assert(_sprite.indexBufferIndex == lastSprite.indexBufferIndex + lastSprite.indexCount); #endif } else { _sprite.indexBufferIndex = _mesh.sortedSpriteList[sortedSpriteIndex].indexBufferIndex; } } else { sortedSpriteIndex = 0; _sprite.indexBufferIndex = 0; } // insert range into _indices int indexCount = _sprite.indexCount; exDebug.Assert(indexCount > 0); _mesh.indices.AddRange(indexCount); // TODO: Array.Copy for (int i = _mesh.indices.Count - 1 - indexCount; i >= _sprite.indexBufferIndex ; --i) { _mesh.indices.buffer[i + indexCount] = _mesh.indices.buffer[i]; } _sprite.updateFlags |= exUpdateFlags.Index; // update other sprites indexBufferIndex for (int i = sortedSpriteIndex; i < _mesh.sortedSpriteList.Count; ++i) { exLayeredSprite otherSprite = _mesh.sortedSpriteList[i]; otherSprite.indexBufferIndex += indexCount; } // insert into _sortedSpriteList _mesh.sortedSpriteList.Insert(sortedSpriteIndex, _sprite); // 这里并没给index buffer分配初始值,所以index很有可能全是0,如果减小index值时,要注意是否还是0,如果是0就不能再减小了。 } }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ internal void SetSpriteBufferSize (exLayeredSprite _sprite, int _vertexCount, int _indexCount) { // 先更新所有depth值,如果遍历到_sprite,则更新的同时重设buffer size UpdateSpriteWhileRecreating.RegisterNewBufferSize(_sprite, _vertexCount, _indexCount); UpdateAllSpritesDepth(); if (UpdateSpriteWhileRecreating.Clear() == false) { // 假如更新depth时没遍历到_sprite,则手动更新 int meshIndex = IndexOfMesh(_sprite); if (meshIndex != -1) { RemoveFromMesh (_sprite, meshList[meshIndex]); } (_sprite as IFriendOfLayer).DoSetBufferSize(_vertexCount, _indexCount); AddToMesh(_sprite, GetMeshToAdd(_sprite)); } }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ private void RemoveIndices (exMesh _mesh, exLayeredSprite _sprite) { exDebug.Assert(_sprite.isInIndexBuffer); if (_sprite.isInIndexBuffer) { // update indices _mesh.indices.RemoveRange(_sprite.indexBufferIndex, _sprite.indexCount); _mesh.updateFlags |= exUpdateFlags.Index; // update indexBufferIndex and sortedSpriteList for (int i = _mesh.sortedSpriteList.Count - 1; i >= 0; --i) { exLayeredSprite otherSprite = _mesh.sortedSpriteList[i]; if (otherSprite.indexBufferIndex > _sprite.indexBufferIndex) { otherSprite.indexBufferIndex -= _sprite.indexCount; exDebug.Assert(otherSprite.indexBufferIndex >= _sprite.indexBufferIndex); } else { exDebug.Assert(otherSprite == _sprite); _mesh.sortedSpriteList.RemoveAt(i); break; } } _sprite.isInIndexBuffer = false; } }
/////////////////////////////////////////////////////////////////////////////// // Internal Functions /////////////////////////////////////////////////////////////////////////////// // ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public int IndexOfMesh (exLayeredSprite _sprite) { Material mat = _sprite.material; for (int i = 0; i < meshList.Count; ++i) { exMesh mesh = meshList[i]; if (object.ReferenceEquals(mesh.material, mat) && mesh != null) { // mesh的引用永远不为空,这里判断的是它是否被unity销毁了 bool containsSprite = (_sprite.spriteIndexInMesh >= 0 && _sprite.spriteIndexInMesh < mesh.spriteList.Count && ReferenceEquals(mesh.spriteList[_sprite.spriteIndexInMesh], _sprite)); //exDebug.Assert(containsSprite == mesh.spriteList.Contains(_sprite), "wrong sprite.spriteIndex"); if (containsSprite) { return i; } } } return -1; }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ private bool IsRenderOrderChangedAmongMeshes (exLayeredSprite _sprite, int _oldMeshIndex) { exLayeredSprite aboveSprite = GetNearestSpriteFromAboveMesh(_oldMeshIndex); if (aboveSprite != null && _sprite > aboveSprite) { return true; } exLayeredSprite belowSprite = GetNearestSpriteFromBelowMesh(_oldMeshIndex); return (belowSprite != null && _sprite < belowSprite); }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public static void TryUpdate (exLayeredSprite _sprite) { if (ReferenceEquals(_sprite, spriteNeedsToSetBufferSize)) { (spriteNeedsToSetBufferSize as IFriendOfLayer).DoSetBufferSize(newVertexCount, newIndexCount); spriteNeedsToSetBufferSize = null; } if (ReferenceEquals(_sprite, spriteNeedsToSetMaterialDirty)) { (spriteNeedsToSetMaterialDirty as IFriendOfLayer).SetMaterialDirty(); spriteNeedsToSetMaterialDirty = null; } }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ private bool IsRenderOrderChangedInMesh (exLayeredSprite _sprite, int _oldMeshIndex, int _oldSortedSpriteIndex) { exMesh mesh = meshList[_oldMeshIndex]; if (_oldSortedSpriteIndex < mesh.sortedSpriteList.Count - 1) { exLayeredSprite aboveSprite = mesh.sortedSpriteList[_oldSortedSpriteIndex + 1]; if (_sprite > aboveSprite) { // 是否要更后渲染 return true; } } if (_oldSortedSpriteIndex > 0) { exLayeredSprite belowSprite = mesh.sortedSpriteList[_oldSortedSpriteIndex - 1]; return (_sprite < belowSprite); } return false; }
private void ShiftSprite (exMesh _src, exMesh _dst, exLayeredSprite _sprite) { #if EX_DEBUG int oldVertexCount = _sprite.vertexCount; #endif RemoveFromMesh(_sprite, _src); #if EX_DEBUG exDebug.Assert (_sprite.vertexCount == oldVertexCount); #endif AddToMesh(_sprite, _dst); #if EX_DEBUG exDebug.Assert (_sprite.vertexCount == oldVertexCount); #endif }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ void DrawNode( exLayeredSprite _node ) { Material material = _node.material; material.SetPass(0); exList<Vector3> vertices = exList<Vector3>.GetTempList(); exList<Vector2> uvs = exList<Vector2>.GetTempList(); exList<int> indices = exList<int>.GetTempList(); exList<Color32> colors = exList<Color32>.GetTempList(); _node.GetBuffers(vertices, uvs, colors, indices); exDebug.Assert(uvs.Count == vertices.Count); //GL.PushMatrix(); //GL.MultMatrix( _node.transform.localToWorldMatrix ); GL.Begin(GL.TRIANGLES); for (int i = 0; i < indices.Count; ++i) { int vertexIndex = indices.buffer[i]; GL.Color ( colors.buffer[vertexIndex] ); GL.TexCoord2 ( uvs.buffer[vertexIndex].x, uvs.buffer[vertexIndex].y ); GL.Vertex ( vertices.buffer[vertexIndex] ); } GL.End(); //GL.PopMatrix(); }