/// <summary> /// Creates a duplicate of the IndexData object. /// </summary> public IndexData Clone() { var clone = new IndexData(); clone._numIndices = _numIndices; if (!_useQuadLayout) { clone.SwitchToGenericData(); Array.Copy(_rawData, clone._rawData, _rawData.Length); } return(clone); }
/// <summary> /// Copies the index data (or a range of it, defined by 'indexID' and 'numIndices') /// of this instance to another IndexData object, starting at a certain target index. /// If the target is not big enough, it will grow to fit all the new indices. /// /// <p>By passing a non-zero <code>offset</code>, you can raise all copied indices /// by that value in the target object.</p> /// </summary> public void CopyTo(IndexData target, int targetIndexId = 0, int offset = 0, int indexId = 0, int numIndices = -1) { if (numIndices < 0 || indexId + numIndices > _numIndices) { numIndices = _numIndices - indexId; } short[] sourceData; int newNumIndices = targetIndexId + numIndices; if (target._numIndices < newNumIndices) { target._numIndices = newNumIndices; if (_sQuadDataNumIndices < newNumIndices) { EnsureQuadDataCapacity(newNumIndices); } } if (_useQuadLayout) { if (target._useQuadLayout) { bool keepsQuadLayout = true; int distance = targetIndexId - indexId; int distanceInQuads = distance / 6; int offsetInQuads = offset / 4; // This code is executed very often. If it turns out that both IndexData // instances use a quad layout, we don't need to do anything here. // // When "distance / 6 == offset / 4 && distance % 6 == 0 && offset % 4 == 0", // the copy operation preserves the quad layout. In that case, we can exit // right away. The code below is a little more complex, though, to avoid the // (surprisingly costly) mod-operations. if (distanceInQuads == offsetInQuads && (offset & 3) == 0 && distanceInQuads * 6 == distance) { keepsQuadLayout = true; } else if (numIndices > 2) { keepsQuadLayout = false; } else { for (int i = 0; i < numIndices; ++i) { keepsQuadLayout = keepsQuadLayout && (GetBasicQuadIndexAt(indexId + i) + offset == GetBasicQuadIndexAt(targetIndexId + i)); } } if (keepsQuadLayout) { return; } target.SwitchToGenericData(); } sourceData = _sQuadData; if ((offset & 3) == 0) // => offset % 4 == 0 { indexId += 6 * offset / 4; offset = 0; EnsureQuadDataCapacity(indexId + numIndices); } } else { if (target._useQuadLayout) { target.SwitchToGenericData(); } sourceData = _rawData; } if (target._rawData.Length < targetIndexId + numIndices) { Array.Resize(ref target._rawData, targetIndexId + numIndices); } if (offset == 0) { Array.Copy(sourceData, indexId, target._rawData, targetIndexId, numIndices); } else { int pos = indexId; int targetPos = targetIndexId; for (int i = 0; i < numIndices; i++) { target._rawData[targetPos] = (short)(sourceData[pos] + offset); pos++; targetPos++; } } }