private void GetLowerRightLinks(int x, int y, int mipLevel, out UVCoordLink hitLink, out UVCoordLink missLink) { // Hit link: Move down a mip level. hitLink = Link(x * 2, y * 2, mipLevel - 1); // Miss link: Move up. missLink = Link(x, y - 1, mipLevel); }
private void GetUpperRightLinks(int x, int y, int mipLevel, out UVCoordLink hitLink, out UVCoordLink missLink) { // Hit link: Move down a mip level. hitLink = Link(x * 2, y * 2, mipLevel - 1); // Miss link: Move up one mip level until a non-upper-right square is reached, // then move to the next square in that sequence. // Or stop if the mip limit is reached (null link). int newX = x, newY = y, newMipLevel = mipLevel; do { newMipLevel += 1; newX /= 2; newY /= 2; } while (newX % 2 == 1 && newY % 2 == 0 && mipLevel != MipCount - 1); if (newX % 2 == 0 && newY % 2 == 0) { if (newMipLevel == MipCount - 1) { missLink = NullLink(); return; } else { missLink = Link(newX, newY + 1, newMipLevel); } } else if (newX % 2 == 0 && newY % 2 == 1) { missLink = Link(newX + 1, newY, newMipLevel); } else /* (newX % 2 == 0 && newY % 2 == 1) */ { missLink = Link(newX, newY - 1, newMipLevel); } }
private void GetLinksForNode(int x, int y, int mipLevel, out UVCoordLink hitLink, out UVCoordLink missLink) { if (x % 2 == 0 && y % 2 == 0) { if (mipLevel == MipCount - 1) { GetRootNodeLinks(out hitLink, out missLink); } else { GetUpperLeftLinks(x, y, mipLevel, out hitLink, out missLink); } } else if (x % 2 == 0 && y % 2 == 1) { GetLowerLeftLinks(x, y, mipLevel, out hitLink, out missLink); } else if (x % 2 == 1 && y % 2 == 1) { GetLowerRightLinks(x, y, mipLevel, out hitLink, out missLink); } else /* (i % 2 == 1 && j % 2 == 0) */ { GetUpperRightLinks(x, y, mipLevel, out hitLink, out missLink); } }
private void GetUpperLeftLinks(int x, int y, int mipLevel, out UVCoordLink hitLink, out UVCoordLink missLink) { // Hit link: Move down a mip level. hitLink = Link(x * 2, y * 2, mipLevel - 1); // Miss link: Move down. missLink = Link(x, y + 1, mipLevel); }
private bool ClimbUpperRightCorner() { x /= 2; y /= 2; mipLevel += 1; if (mipLevel == MipCount - 1) { finished = true; } else { UVCoordLink hitLink = Link(x * 2, y * 2, mipLevel - 1); UVCoordLink missLink = NullLink(); try { this.curHitLink = hitLink; this.hitLinkPixels [mipLevel][x + mipWidths[mipLevel] * y] = hitLink; this.curMissLink = missLink; this.missLinkPixels[mipLevel][x + mipWidths[mipLevel] * y] = missLink; } catch (System.IndexOutOfRangeException) { Debug.LogError("tried to index for mipLevel: " + mipLevel + " and x " + x + " and y " + y); } } return(!finished); }
private UVCoordLink Link(int x, int y, int mipLevel) { if (mipLevel == -1) { return(UVCoordLink.NullLink()); } else { return(new UVCoordLink(x, y, mipLevel, mipWidths[mipLevel])); } }
private void GetRootNodeLinks(out UVCoordLink hitLink, out UVCoordLink missLink) { if (MipCount == 1) { //Debug.LogWarning("Special case detected again: Single pixel texture."); hitLink = UVCoordLink.NullLink(); } else { //Debug.Log("Root node link. MipCount is " + MipCount); hitLink = new UVCoordLink(0, 0, MipCount - 2, 2); //Debug.Log("GetRootNodeLink. Returning hit link: " + hitLink); } missLink = UVCoordLink.NullLink(); }
private UVCoordLink NullLink() { return(UVCoordLink.NullLink()); }
// Hit Links: Down one mip level if possible (x * 2, y * 2), else null // Miss Links: // s0 s3 --> (up-and-next until a non-visited node is found,) // | ^ or null if a miss ends traversal) // v | // s1 -> s2 /// <summary> Sets the output hitLink and missLink coordinate links for the node /// just arrived at by the Step(). Returns true if there are more steps to take, /// false otherwise. </summary> public bool Step() { //Debug.Log("Stepping."); if (finished) { Debug.LogError("Already finished walking."); return(true); } // Initialization case if (mipLevel == -1 && x == -1 && y == -1) { this.x = 0; this.y = 0; this.mipLevel = mipWidths.Length - 1; UVCoordLink hitLink, missLink; GetRootNodeLinks(out hitLink, out missLink); this.curHitLink = hitLink; this.hitLinkPixels [mipLevel][x + mipWidths[mipLevel] * y] = hitLink; this.curMissLink = missLink; this.missLinkPixels[mipLevel][x + mipWidths[mipLevel] * y] = missLink; if (hitLink.isNull) { Debug.LogWarning("Special case detected: Base texture is one pixel."); finished = true; } return(!finished); } else { if (!finishing) { if (curHitLink.isNull) { // Follow miss link. this.x = curMissLink.X(TexWidth); // Debug.Log("TexWidth is: " + TexWidth); // Debug.Log("MipLevelInteger is: " + curMissLink.MipLevelInteger + " and MipWidth is " + curMissLink.MipWidth(curMissLink.MipLevelInteger, TexWidth)); // Debug.Log("Miss link X: " + curMissLink.X(TexWidth) + "; Miss link Y: " + curHitLink.Y(TexWidth)); this.y = curMissLink.Y(TexWidth); this.mipLevel = curMissLink.MipLevelInteger; //Debug.Log("Followed miss link: " + curMissLink + ". Current position is: " + this); } else { // Follow hit link. this.x = curHitLink.X(TexWidth); this.y = curHitLink.Y(TexWidth); this.mipLevel = curHitLink.MipLevelInteger; //Debug.Log("Followed hit link: " + curHitLink + ". Current position is: " + this); } UVCoordLink hitLink, missLink; GetLinksForNode(this.x, this.y, this.mipLevel, out hitLink, out missLink); this.curHitLink = hitLink; this.hitLinkPixels [mipLevel][x + mipWidths[mipLevel] * y] = hitLink; this.curMissLink = missLink; this.missLinkPixels[mipLevel][x + mipWidths[mipLevel] * y] = missLink; if (this.x == mipWidths[mipLevel] - 1 && this.y == 0 && mipLevel == 0) { // Hit upper-right corner of the mip-0 texture, start finishing. //Debug.Log("Finishing began."); finishing = true; } else { return(true); } } if (finishing) { // To finish, travel up one mip level to successive upper-right corners. return(ClimbUpperRightCorner()); } //Debug.LogError("Should never reach here."); return(true); } }