@@ -371,31 +371,16 @@ void RenderedTarget::setHeight(qreal height)
371371Rect RenderedTarget::getBounds () const
372372{
373373 // https://github.com/scratchfoundation/scratch-render/blob/c3ede9c3d54769730c7b023021511e2aba167b1f/src/Rectangle.js#L33-L55
374- if (!m_costume || !m_skin || !m_texture.isValid () || !m_cpuTexture.isValid ())
375- return Rect (m_x, m_y, m_x, m_y);
376-
377- const double textureScale = m_skin->getTextureScale (m_cpuTexture);
378- const double bitmapRes = m_costume->bitmapResolution ();
379- const double width = m_cpuTexture.width () * m_size / textureScale;
380- const double height = m_cpuTexture.height () * m_size / textureScale;
381- const double originX = m_costume->rotationCenterX () * m_size / bitmapRes - width / 2 ;
382- const double originY = -m_costume->rotationCenterY () * m_size / bitmapRes + height / 2 ;
383- const double rot = -rotation () * pi / 180 ;
384- const double sinRot = std::sin (rot);
385- const double cosRot = std::cos (rot);
386374 double left = std::numeric_limits<double >::infinity ();
387375 double top = -std::numeric_limits<double >::infinity ();
388376 double right = -std::numeric_limits<double >::infinity ();
389377 double bottom = std::numeric_limits<double >::infinity ();
390378
391- const std::vector<QPoint > &points = hullPoints ();
379+ const std::vector<QPointF > &points = transformedHullPoints ();
392380
393381 for (const QPointF &point : points) {
394- double x = point.x () * m_size / textureScale / bitmapRes - width / 2 ;
395- double y = height / 2 - point.y () * m_size / textureScale / bitmapRes;
396- const QPointF transformed = transformPoint (x, y, originX, originY, sinRot, cosRot);
397- x = transformed.x () * (m_mirrorHorizontally ? -1 : 1 );
398- y = transformed.y ();
382+ const double x = point.x ();
383+ const double y = point.y ();
399384
400385 if (x < left)
401386 left = x;
@@ -733,6 +718,8 @@ void RenderedTarget::calculatePos()
733718 else
734719 setTransformOrigin (QQuickItem::Center);
735720 }
721+
722+ m_transformedHullDirty = true ;
736723}
737724
738725void RenderedTarget::calculateRotation ()
@@ -764,6 +751,8 @@ void RenderedTarget::calculateRotation()
764751 if (m_mirrorHorizontally != oldMirrorHorizontally)
765752 emit mirrorHorizontallyChanged ();
766753 }
754+
755+ m_transformedHullDirty = true ;
767756}
768757
769758void RenderedTarget::calculateSize ()
@@ -779,6 +768,8 @@ void RenderedTarget::calculateSize()
779768
780769 if (wasValid && m_cpuTexture.handle () != oldTexture)
781770 m_convexHullDirty = true ;
771+
772+ m_transformedHullDirty = true ;
782773 }
783774}
784775
@@ -811,6 +802,42 @@ void RenderedTarget::updateHullPoints()
811802 // TODO: Apply graphic effects (#117)
812803}
813804
805+ const std::vector<QPointF> &RenderedTarget::transformedHullPoints () const
806+ {
807+ // https://github.com/scratchfoundation/scratch-render/blob/9fe90e8f4c2da35d4684359f84b69c264d884133/src/Drawable.js#L594-L616
808+ if (!m_transformedHullDirty)
809+ return m_transformedHullPoints;
810+
811+ m_transformedHullPoints.clear ();
812+
813+ if (!m_costume || !m_skin || !m_texture.isValid () || !m_cpuTexture.isValid ())
814+ return m_transformedHullPoints;
815+
816+ const double textureScale = m_skin->getTextureScale (m_cpuTexture);
817+ const double bitmapRes = m_costume->bitmapResolution ();
818+ const double width = m_cpuTexture.width () * m_size / textureScale;
819+ const double height = m_cpuTexture.height () * m_size / textureScale;
820+ const double originX = m_costume->rotationCenterX () * m_size / bitmapRes - width / 2 ;
821+ const double originY = -m_costume->rotationCenterY () * m_size / bitmapRes + height / 2 ;
822+ const double rot = -rotation () * pi / 180 ;
823+ const double sinRot = std::sin (rot);
824+ const double cosRot = std::cos (rot);
825+
826+ const std::vector<QPoint> &points = hullPoints ();
827+ m_transformedHullPoints.reserve (points.size ());
828+
829+ for (const QPoint &point : points) {
830+ double x = point.x () * m_size / textureScale / bitmapRes - width / 2 ;
831+ double y = height / 2 - point.y () * m_size / textureScale / bitmapRes;
832+ const QPointF transformed = transformPoint (x, y, originX, originY, sinRot, cosRot);
833+ x = transformed.x () * (m_mirrorHorizontally ? -1 : 1 );
834+ y = transformed.y ();
835+ m_transformedHullPoints.push_back (QPointF (x, y));
836+ }
837+
838+ return m_transformedHullPoints;
839+ }
840+
814841bool RenderedTarget::containsLocalPoint (const QPointF &point) const
815842{
816843 return textureManager ()->textureContainsPoint (m_cpuTexture, point, m_graphicEffects);
0 commit comments