/////////////////////////////////////////////////////////////////////////////// // Public Functions /////////////////////////////////////////////////////////////////////////////// // ------------------------------------------------------------------ /// Create a new GameObject contains an exMesh component // ------------------------------------------------------------------ public static exMesh Create(exLayer _layer) { #if UNITY_EDITOR GameObject go = UnityEditor.EditorUtility.CreateGameObjectWithHideFlags("", exReleaseFlags.hideAndDontSave | exReleaseFlags.notEditable); #else GameObject go = new GameObject(); // 当在EX_DEBUG模式下,如果显示着GO的Inspector,再启动游戏,由于GO是DontSave的,会先被销毁。这时Unity将会报错,但不影响运行,这个问题在类似插件中也会存在。 go.hideFlags = exReleaseFlags.hideAndDontSave | exReleaseFlags.notEditable; #endif exMesh res = go.AddComponent <exMesh>(); res.UpdateDebugName(_layer); res.Init(); return(res); }
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: // ------------------------------------------------------------------ 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; } }
// ------------------------------------------------------------------ // 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: // ------------------------------------------------------------------ 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"); }
// ------------------------------------------------------------------ /// 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"); }