View Issue Details
ID | Project | Category | Date Submitted | Last Update | |
---|---|---|---|---|---|
0000024 | AI War 1 / Classic | Graphical Bug | Oct 2, 2010 9:01 pm | Oct 5, 2010 6:46 pm | |
Reporter | Chris_McElligottPark | Assigned To | keith.lamothe | ||
Status | resolved | Resolution | fixed | ||
Summary | 0000024: Angled Line Accuracy | ||||
Description | Keith, whenever makes sense for you -- for the prerelease if possible wouldn't be bad -- can you take a look at DrawLineAngled? There's some wonkiness there (and always has been, back to the SlimDX days and before) with it drawing lines of different thicknesses. Also, if you have two points, it draws them slightly differently between P1 and P2 versus P2 and P1. That second issue is completely because of some of the offsetting stuff I'm doing in an attempt to make the center of a 3px line line up with the center of a 1px line, rather than having them edge-aligned. To some extent, all the many (many, many) different permutations I've tried for the offsetting have just made things worse. At the very least a pair of fresh eyes would be helpful. | ||||
Tags | No tags attached. | ||||
Internal Weight | |||||
|
The code, for anyone who wants to chip in: public bool DrawLineAngled( float P1X, float P1Y, float P2X, float P2Y, float FullThickness, Color DiffuseColor, ShaderType ShaderType, GameImage OverridingImage, float UVX, float UVY, UVUseType UVUseType, DrawIn DrawIn, bool DisallowPointFlipping ) { #region Img Retrieval GameImage Img; if ( OverridingImage != null ) Img = OverridingImage; else { if ( lineImage == null ) lineImage = Game.Instance.GetGameImage( "Line" ); Img = lineImage; } if ( Img == null ) return false; if ( Img.Texture == null ) { if ( !Img.IsCurrentlyLoading ) Img.QueueForLoading(); return false; } if ( !this.ActuallyDrawImages ) return false; #endregion Material mat = Img.GetMaterial( ShaderType ); if ( mat == null ) return false; SpriteObject obj = Game.Instance.GetSpriteForImage( Img ); if ( obj == null ) return false; if ( DrawIn == DrawIn.GameUnits ) { P1X -= Game.Instance.ViewportX; P1Y -= Game.Instance.ViewportY; P2X -= Game.Instance.ViewportX; P2Y -= Game.Instance.ViewportY; } if ( this.UseRenderScale ) { FullThickness *= this.RenderScale; P1X = Mathf.RoundToInt( P1X * this.RenderScale ); P1Y = Mathf.RoundToInt( P1Y * this.RenderScale ); P2X = Mathf.RoundToInt( P2X * this.RenderScale ); P2Y = Mathf.RoundToInt( P2Y * this.RenderScale ); } else if ( DrawIn == DrawIn.GameUnits ) { P1X = Mathf.RoundToInt( P1X * this.RenderScale ); P1Y = Mathf.RoundToInt( P1Y * this.RenderScale ); P2X = Mathf.RoundToInt( P2X * this.RenderScale ); P2Y = Mathf.RoundToInt( P2Y * this.RenderScale ); } if ( this.UseDiffuseOffset ) DiffuseColor = ColorMath.SubtractColors( DiffuseColor, DiffuseOffsets ); if ( !DisallowPointFlipping && ( P1X < P2X || P1Y < P2Y ) ) { float p3X = P2X; float p3Y = P2Y; P2X = P1X; P2Y = P1Y; P1X = p3X; P1Y = p3Y; } #region half float half = FullThickness / 2f; if ( P1X > P2X ) { P1X -= half; P2X -= half; } else { P1X += half; P2X += half; } if ( P1Y < P2Y ) { P1Y -= half; P2Y -= half; } else { P1Y += half; P2Y += half; } #endregion float length = (float)Mat.DistanceBetweenPointsD( P1X, P1Y, P2X, P2Y ); float angleDegrees = (float)Mat.AngleBetweenPointsDegreesDouble( P1X, P1Y, P2X, P2Y ); Vector3 position = Game.Instance.MainCameraCamera.ScreenToWorldPoint( new Vector3( P1X, this.ActualHeight - P1Y, ZDepth ) ); Quaternion quaternion = Quaternion.identity; angleDegrees = -angleDegrees; quaternion = this.RotateAround( new Vector3( position.x, position.y, position.z ), ref position, new Vector3( 0, 0, 1 ), ref angleDegrees ); DelayedRenderer dr = DelayedRenderer.GetNextFree(); switch ( UVUseType ) { case UVUseType.None: { float widthScale = length / Img.ImageSize; float heightScale = FullThickness / Img.ImageSize; Matrix4x4 matrix = Matrix4x4.TRS( position, quaternion, new Vector3( widthScale, heightScale, 1 ) ); dr.SetUVUseTypeNone( Img.ID, Img.Texture, ShaderType, mat, matrix, obj, DiffuseColor ); } break; case UVUseType.ExtendedTiled: { //float widthScale = length / Img.ImageSize; float heightScale = FullThickness / Img.ImageSize; Matrix4x4 matrix = Matrix4x4.TRS( position, quaternion, new Vector3( 1, heightScale, 1 ) ); dr.SetUVUseTypeExtended( Img.ID, Img.Texture, ShaderType, mat, matrix, obj, DiffuseColor, false, false, length, Img.ImageSize, UVX, UVY ); } break; case UVUseType.ExtendedStretched: { float widthScale = length / Img.ImageSize; float heightScale = FullThickness / Img.ImageSize; Matrix4x4 matrix = Matrix4x4.TRS( position, quaternion, new Vector3( widthScale, heightScale, 1 ) ); dr.SetUVUseTypeExtended( Img.ID, Img.Texture, ShaderType, mat, matrix, obj, DiffuseColor, false, false, Img.ImageSize, Img.ImageSize, UVX, UVY ); } break; } return true; } |
|
* Improvements to angled line drawing accuracy. |
|
Still not perfect, but it's certainly much improved! Keith's revised code: public bool DrawLineAngled( float P1X, float P1Y, float P2X, float P2Y, float FullThickness, Color DiffuseColor, ShaderType ShaderType, GameImage OverridingImage, float UVX, float UVY, UVUseType UVUseType, DrawIn DrawIn, bool DisallowPointFlipping ) { #region Img Retrieval GameImage Img; if ( OverridingImage != null ) Img = OverridingImage; else { if ( lineImage == null ) lineImage = Game.Instance.GetGameImage( "Line" ); Img = lineImage; } if ( Img == null ) return false; if ( Img.Texture == null ) { if ( !Img.IsCurrentlyLoading ) Img.QueueForLoading(); return false; } if ( !this.ActuallyDrawImages ) return false; #endregion Material mat = Img.GetMaterial( ShaderType ); if ( mat == null ) return false; SpriteObject obj = Game.Instance.GetSpriteForImage( Img ); if ( obj == null ) return false; if ( DrawIn == DrawIn.GameUnits ) { P1X -= Game.Instance.ViewportX; P1Y -= Game.Instance.ViewportY; P2X -= Game.Instance.ViewportX; P2Y -= Game.Instance.ViewportY; } if ( this.UseRenderScale ) { FullThickness *= this.RenderScale; P1X = P1X * this.RenderScale; P1Y = P1Y * this.RenderScale; P2X = P2X * this.RenderScale; P2Y = P2Y * this.RenderScale; } else if ( DrawIn == DrawIn.GameUnits ) { P1X = P1X * this.RenderScale; P1Y = P1Y * this.RenderScale; P2X = P2X * this.RenderScale; P2Y = P2Y * this.RenderScale; } if ( this.UseDiffuseOffset ) DiffuseColor = ColorMath.SubtractColors( DiffuseColor, DiffuseOffsets ); if ( !DisallowPointFlipping && ( P1X < P2X || P1Y < P2Y ) ) { float p3X = P2X; float p3Y = P2Y; P2X = P1X; P2Y = P1Y; P1X = p3X; P1Y = p3Y; } int relativeQuadrantOfPoint2; if ( P1X < P2X ) { if ( P1Y < P2Y ) { relativeQuadrantOfPoint2 = 2; } else { relativeQuadrantOfPoint2 = 3; } } else { if ( P1Y < P2Y ) { relativeQuadrantOfPoint2 = 1; } else { relativeQuadrantOfPoint2 = 4; } } #region half float half = FullThickness / 2f; if ( relativeQuadrantOfPoint2 == 1 ) { //DiffuseColor = Color.red; P1X -= half; P2X -= half; P1Y -= half; P2Y -= half; } else if ( relativeQuadrantOfPoint2 == 2 ) { //DiffuseColor = Color.green; P1X -= half; P2X -= half; P1Y += half; P2Y += half; } else if ( relativeQuadrantOfPoint2 == 3 ) { //DiffuseColor = Color.blue; P1X += half; P2X += half; P1Y += half; P2Y += half; } else { //DiffuseColor = Color.yellow; P1X += half; P2X += half; P1Y -= half; P2Y -= half; } #endregion float length = (float)Mat.DistanceBetweenPointsD( P1X, P1Y, P2X, P2Y ); float angleDegrees = (float)Mat.AngleBetweenPointsDegreesDouble( P1X, P1Y, P2X, P2Y ); Vector3 position = Game.Instance.MainCameraCamera.ScreenToWorldPoint( new Vector3( P1X, this.ActualHeight - P1Y, ZDepth ) ); Quaternion quaternion = Quaternion.identity; angleDegrees = -angleDegrees; quaternion = this.RotateAround( new Vector3( position.x, position.y, position.z ), ref position, new Vector3( 0, 0, 1 ), ref angleDegrees ); DelayedRenderer dr = DelayedRenderer.GetNextFree(); switch ( UVUseType ) { case UVUseType.None: { float widthScale = length / Img.ImageSize; float heightScale = FullThickness / Img.ImageSize; Matrix4x4 matrix = Matrix4x4.TRS( position, quaternion, new Vector3( widthScale, heightScale, 1 ) ); dr.SetUVUseTypeNone( Img.ID, Img.Texture, ShaderType, mat, matrix, obj, DiffuseColor ); } break; case UVUseType.ExtendedTiled: { //float widthScale = length / Img.ImageSize; float heightScale = FullThickness / Img.ImageSize; Matrix4x4 matrix = Matrix4x4.TRS( position, quaternion, new Vector3( 1, heightScale, 1 ) ); dr.SetUVUseTypeExtended( Img.ID, Img.Texture, ShaderType, mat, matrix, obj, DiffuseColor, false, false, length, Img.ImageSize, UVX, UVY ); } break; case UVUseType.ExtendedStretched: { float widthScale = length / Img.ImageSize; float heightScale = FullThickness / Img.ImageSize; Matrix4x4 matrix = Matrix4x4.TRS( position, quaternion, new Vector3( widthScale, heightScale, 1 ) ); dr.SetUVUseTypeExtended( Img.ID, Img.Texture, ShaderType, mat, matrix, obj, DiffuseColor, false, false, Img.ImageSize, Img.ImageSize, UVX, UVY ); } break; } return true; } #endregion Anyone else have any ideas? |
|
Can you tell me what specifically it's not doing properly now? Is the center of the exact end of the line supposed to coincide pixel-perfect exactly with the center of the endpoint-ship? |
|
Right. The center of the endpoint of the line should be on the center of ship. |
|
Ok, there's a few more things I can try, then. |
|
Ok -- thanks. It's already much better based on what you did, though. I never could get it that good. ;) |
|
* Further improvements to line drawing accuracy. How about now? :) |
|
Just realized that my offset computation duplicates a computation (line length) that is done later, so that could be optimized a bit, but let's see if it actually works. |
|
Looks great! Wow, that's so incredibly much better. I put in that last little efficiency boost with the length only to be calculated once, and that didn't seem to affect accuracy. So looks like this can FINALLY be put to rest, after almost two years! Nice work, Keith! :D |
Date Modified | Username | Field | Change |
---|---|---|---|
Oct 2, 2010 9:01 pm | Chris_McElligottPark | New Issue | |
Oct 2, 2010 9:01 pm | Chris_McElligottPark | Status | new => assigned |
Oct 2, 2010 9:01 pm | Chris_McElligottPark | Assigned To | => keith.lamothe |
Oct 2, 2010 9:02 pm | Chris_McElligottPark | Note Added: 0000007 | |
Oct 4, 2010 6:27 pm | keith.lamothe | Note Added: 0000304 | |
Oct 4, 2010 6:27 pm | keith.lamothe | Status | assigned => resolved |
Oct 4, 2010 6:27 pm | keith.lamothe | Resolution | open => fixed |
Oct 4, 2010 7:24 pm | Chris_McElligottPark | Note Added: 0000306 | |
Oct 4, 2010 7:24 pm | Chris_McElligottPark | Status | resolved => feedback |
Oct 4, 2010 7:24 pm | Chris_McElligottPark | Resolution | fixed => reopened |
Oct 5, 2010 12:24 am | keith.lamothe | Note Added: 0000346 | |
Oct 5, 2010 12:25 am | Chris_McElligottPark | Note Added: 0000347 | |
Oct 5, 2010 12:25 am | Chris_McElligottPark | Status | feedback => assigned |
Oct 5, 2010 12:29 am | keith.lamothe | Note Added: 0000348 | |
Oct 5, 2010 12:37 am | Chris_McElligottPark | Note Added: 0000350 | |
Oct 5, 2010 4:34 pm | keith.lamothe | Note Added: 0000399 | |
Oct 5, 2010 4:34 pm | keith.lamothe | Status | assigned => resolved |
Oct 5, 2010 4:34 pm | keith.lamothe | Resolution | reopened => fixed |
Oct 5, 2010 4:35 pm | keith.lamothe | Note Added: 0000400 | |
Oct 5, 2010 6:46 pm | Chris_McElligottPark | Note Added: 0000402 | |
Apr 14, 2014 9:29 am | Chris_McElligottPark | Category | Bug - Graphical Issue => Graphical Bug |