diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml index 34ba687243..4457774e76 100644 --- a/Docs/Luadoc/LuaDocumentation.xml +++ b/Docs/Luadoc/LuaDocumentation.xml @@ -4236,7 +4236,7 @@ save yourself some time, copy this for undocumented things: [02 Sprite.lua] Call RageTexture:rate( fRate ) on the texture. - Scale the Sprite to width fWidth and height fHeight clipping if the dimensions do not match. + Scale the Sprite to width fWidth and height fHeight clipping dimension that would stick out. Set the Sprite's state to iNewState. diff --git a/src/Sprite.cpp b/src/Sprite.cpp index c3af0d668e..389c7568f4 100644 --- a/src/Sprite.cpp +++ b/src/Sprite.cpp @@ -30,6 +30,8 @@ Sprite::Sprite() m_fRememberedClipWidth = -1; m_fRememberedClipHeight = -1; + m_fRememberedCropWidth = -1; + m_fRememberedCropHeight = -1; m_fTexCoordVelocityX = 0; m_fTexCoordVelocityY = 0; @@ -56,6 +58,8 @@ Sprite::Sprite( const Sprite &cpy ): memcpy( m_CustomPosCoords, cpy.m_CustomPosCoords, sizeof(m_CustomPosCoords) ); CPY( m_fRememberedClipWidth ); CPY( m_fRememberedClipHeight ); + CPY( m_fRememberedCropWidth ); + CPY( m_fRememberedCropHeight ); CPY( m_fTexCoordVelocityX ); CPY( m_fTexCoordVelocityY ); #undef CPY @@ -295,6 +299,11 @@ void Sprite::SetTexture( RageTexture *pTexture ) if( m_fRememberedClipWidth != -1 && m_fRememberedClipHeight != -1 ) ScaleToClipped( m_fRememberedClipWidth, m_fRememberedClipHeight ); + if( m_fRememberedCropWidth != -1 && m_fRememberedCropHeight != -1 ) + { + CropTo(m_fRememberedCropWidth, m_fRememberedCropHeight); + } + // Load default states if we haven't before. if( m_States.empty() ) LoadStatesFromTexture(); @@ -871,125 +880,97 @@ void Sprite::SetTexCoordVelocity(float fVelX, float fVelY) m_fTexCoordVelocityY = fVelY; } -void Sprite::ScaleToClipped( float fWidth, float fHeight ) +void Sprite::ScaleToClipped( float width, float height ) { - m_fRememberedClipWidth = fWidth; - m_fRememberedClipHeight = fHeight; + m_fRememberedClipWidth = width; + m_fRememberedClipHeight = height; if( !m_pTexture ) - return; - - float fScaleFudgePercent = 0.15f; // scale up to this amount in one dimension to avoid clipping. - - // save the original X and Y. We're going to restore them later. - float fOriginalX = GetX(); - float fOriginalY = GetY(); - - if( fWidth != -1 && fHeight != -1 ) { - // this is probably a background graphic or something not intended to be a CroppedSprite - Sprite::StopUsingCustomCoords(); - - // first find the correct zoom - Sprite::ScaleToCover( RectF(0, 0, fWidth, fHeight) ); - // find which dimension is larger - bool bXDimNeedsToBeCropped = GetZoomedWidth() > fWidth+0.01; - - if( bXDimNeedsToBeCropped ) // crop X - { - float fPercentageToCutOff = (this->GetZoomedWidth() - fWidth) / this->GetZoomedWidth(); - fPercentageToCutOff = max( fPercentageToCutOff-fScaleFudgePercent, 0 ); - float fPercentageToCutOffEachSide = fPercentageToCutOff / 2; - - // generate a rectangle with new texture coordinates - RectF fCustomImageRect( - fPercentageToCutOffEachSide, - 0, - 1 - fPercentageToCutOffEachSide, - 1 ); - SetCustomImageRect( fCustomImageRect ); - } - else // crop Y - { - float fPercentageToCutOff = (this->GetZoomedHeight() - fHeight) / this->GetZoomedHeight(); - fPercentageToCutOff = max( fPercentageToCutOff-fScaleFudgePercent, 0 ); - float fPercentageToCutOffEachSide = fPercentageToCutOff / 2; - - // generate a rectangle with new texture coordinates - RectF fCustomImageRect( - 0, - fPercentageToCutOffEachSide, - 1, - 1 - fPercentageToCutOffEachSide ); - SetCustomImageRect( fCustomImageRect ); - } - m_size = RageVector2( fWidth, fHeight ); - SetZoom( 1 ); + return; + } + // -1 means do nothing because it's the default value and means no + // remembered dimensions. + if(width == -1 || height == -1) + { + return; + } + // The previous implementation used a custom image rect and ended with a + // zoom of 1, didn't actually clip unless the dest was larger, and didn't + // reverse itself correctly, so it couldn't be used on an image that + // changed. It also included a fudge factor which apparently existed + // solely to make the function only work when scaling up. + // Also, ScaleToClipped and CropTo were both setting RememberedClip, so + // after SetTexture, what was a CropTo operation was turned into a + // ScaleToClipped operation. + // This is much a much simpler implementation without the problems. + // The only caveat to this implementation is that GetWidth doesn't factor + // in cropping, so someone using GetWidth to put an outline around the + // sprite afterwards will end up with the wrong size. -Kyz + SetCropTop(0); + SetCropBottom(0); + SetCropLeft(0); + SetCropRight(0); + float uzw= GetUnzoomedWidth(); + float uzh= GetUnzoomedHeight(); + float xz= width / uzw; + float yz= height / uzh; + if(xz > yz) + { + SetZoom(xz); + float clip_amount= (1 - (height / (uzh * xz))) / 2; + SetCropTop(clip_amount); + SetCropBottom(clip_amount); + } + else + { + SetZoom(yz); + float clip_amount= (1 - (width / (uzw * yz))) / 2; + SetCropLeft(clip_amount); + SetCropRight(clip_amount); } - - // restore original XY - SetXY( fOriginalX, fOriginalY ); } -// magic hurr -// This code should either be removed or refactored in the future -aj -void Sprite::CropTo( float fWidth, float fHeight ) +void Sprite::CropTo( float width, float height ) { - m_fRememberedClipWidth = fWidth; - m_fRememberedClipHeight = fHeight; - + m_fRememberedCropWidth= width; + m_fRememberedCropHeight= height; if( !m_pTexture ) - return; - - // save the original X&Y. We're going to restore them later. - float fOriginalX = GetX(); - float fOriginalY = GetY(); - - if( fWidth != -1 && fHeight != -1 ) { - // this is probably a background graphic or something not intended to be a CroppedSprite - Sprite::StopUsingCustomCoords(); - - // first find the correct zoom - Sprite::ScaleToCover( RectF(0, 0, fWidth, fHeight) ); - // find which dimension is larger - bool bXDimNeedsToBeCropped = GetZoomedWidth() > fWidth+0.01; - - if( bXDimNeedsToBeCropped ) // crop X - { - float fPercentageToCutOff = (this->GetZoomedWidth() - fWidth) / this->GetZoomedWidth(); - float fPercentageToCutOffEachSide = fPercentageToCutOff / 2; - - // generate a rectangle with new texture coordinates - RectF fCustomImageRect( - fPercentageToCutOffEachSide, - 0, - 1 - fPercentageToCutOffEachSide, - 1 ); - SetCustomImageRect( fCustomImageRect ); - } - else // crop Y - { - float fPercentageToCutOff = (this->GetZoomedHeight() - fHeight) / this->GetZoomedHeight(); - float fPercentageToCutOffEachSide = fPercentageToCutOff / 2; - - // generate a rectangle with new texture coordinates - RectF fCustomImageRect( - 0, - fPercentageToCutOffEachSide, - 1, - 1 - fPercentageToCutOffEachSide ); - SetCustomImageRect( fCustomImageRect ); - } - m_size = RageVector2( fWidth, fHeight ); - SetZoom( 1 ); + return; } - - // restore original XY - SetXY( fOriginalX, fOriginalY ); + // -1 means do nothing because it's the default value and means no + // remembered dimensions. + if(width == -1 || height == -1) + { + return; + } + // The previous implementation was identical to ScaleToClipped's previous + // implementation (including the not working correctly part), but without + // the fudge factor. Why was a function named "CropTo" changing the scale + // of the sprite? That just seems strange and counterintuitive to me, so + // this implementation doesn't change the scale at all. + // Again, this has the caveat that GetWidth doesn't factor in cropping. -Kyz + float zw= GetZoomedWidth(); + float zh= GetZoomedHeight(); + float xf= width / zw; + float yf= height / zh; + float xc= (1 - xf) / 2; + float yc= (1 - yf) / 2; + if(xf > 1) + { + xc= 0; + } + if(yf > 1) + { + yc= 0; + } + SetCropLeft(xc); + SetCropRight(xc); + SetCropTop(yc); + SetCropBottom(yc); } -// end magic void Sprite::StretchTexCoords( float fX, float fY ) { diff --git a/src/Sprite.h b/src/Sprite.h index 0697fc8aec..435a85742a 100644 --- a/src/Sprite.h +++ b/src/Sprite.h @@ -67,10 +67,10 @@ public: * @brief Scale the Sprite while maintaining the aspect ratio. * * It has to fit within and become clipped to the given parameters. - * @param fWidth the new width. - * @param fHeight the new height. */ - void ScaleToClipped( float fWidth, float fHeight ); - void CropTo( float fWidth, float fHeight ); + * @param width the new width. + * @param height the new height. */ + void ScaleToClipped( float width, float height ); + void CropTo( float width, float height ); // Commands virtual void PushSelf( lua_State *L ); @@ -124,6 +124,7 @@ private: // Remembered clipped dimensions are applied on Load(). // -1 means no remembered dimensions; float m_fRememberedClipWidth, m_fRememberedClipHeight; + float m_fRememberedCropWidth, m_fRememberedCropHeight; float m_fTexCoordVelocityX; float m_fTexCoordVelocityY;