SVG vector graphics rendering fun

letmethink

  • *
  • Posts: 2545
So... I got bored again. I implemented basic vector rendering from the extras folder which was interesting (still debating where I should post these topics before I share the resource). I may wrap this as well into something useable at some point. (ignore the actual graphic I am using - I had it lying around somewhere (I made it at some point)).

<a href="http://lmtproductions.weebly.com/uploads/2/0/7/9/20793336/vectors_fun.swf" target="_blank" class="new_win">http://lmtproductions.weebly.com/uploads/2/0/7/9/20793336/vectors_fun.swf</a>

(move mouse to scale graphic)

Note: I can actually do more with it - the actual example just shows that I can actually get it to render. In reality I can do whatever you can do to a bitmap image with it. (Actors' sprite)

« Last Edit: August 07, 2015, 03:30:43 am by letmethink »
~Letmethink

SadiQ

  • Posts: 1795
Is that a SVG file? Is there a trick there or has openFl finally fixed their vector drawing issues?
Both Hectate and I tried rendering vector graphics without much success  a while ago, so I'm glad you managed to make it work.
This could be very useful.
Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

letmethink

  • *
  • Posts: 2545
I don't think much has changed for quite a while. It is indeed an svg. I used this library for rendering: https://github.com/openfl/svg
~Letmethink

SadiQ

  • Posts: 1795
It seems the latest change to that file was 3 months ago, and the version that ships with stencyl is older than that.
Glad to hear that things are improving. Great job there mate :)
Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

letmethink

  • *
  • Posts: 2545
Btw, I'm fairly sure that library doesn't ship with Stencyl as I had to import it myself.
~Letmethink

yoplalala

  • *
  • Posts: 1632
Brilliant ! I would surely use it !

SadiQ

  • Posts: 1795
Btw, I'm fairly sure that library doesn't ship with Stencyl as I had to import it myself.
Look there:  Stencyl\plaf\haxe\lib\svg\
Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

letmethink

  • *
  • Posts: 2545
Just when I had this all typed out:
Btw, I'm fairly sure that library doesn't ship with Stencyl as I had to import it myself.
Look there:  Stencyl\plaf\haxe\lib\svg\
Oh wow I'm blind. All the files seem to be larger in the Stencyl installation so I must be using an outdated version.

 :-X

For now I'll write a quick tutorial on how I got this up and running. First, grab the .zip of the svg package here: https://github.com/openfl/svg/archive/master.zip

Next you can unzip this. Inside you will find a folder called format. Copy that and paste it into your Stencyl installation at: C:\Program Files (x86)\Stencyl\plaf\haxe\lib\openfl\openfl or whatever your path for Stencyl is. Now you have imported that library and can use it.

Next from within the events of Stencyl, (or wherever you want to render it from, use an import statement and import these:
Code: (haxe) [Select]
import openfl.Assets;
import openfl.display.Shape;
import openfl.display.Sprite;
import format.SVG;
Next, in your game's extras folder (if you don't have one or don't know what I'm on about, read here: http://community.stencyl.com/index.php/topic,24729.0.html) paste a svg image. Then, the code I use for my dynamic resizing is this:

In a when created event:
Code: (haxe) [Select]
var svg : SVG = new SVG(Assets.getText("assets/data/openfl.svg"));
var shape : Shape  = new Shape();
svg.render(shape.graphics,10,10,10,10);
engine.hudLayer.addChild (shape);

In a when drawing event:
Code: (haxe) [Select]
shape.parent.removeChild(shape);
shape.graphics.clear();
svg.render(shape.graphics,0,0,Math.round(getMouseX()),Math.round(getMouseY()));
engine.hudLayer.addChild (shape);

Then, if you build your game, you should see the behaviour I see.
~Letmethink

letmethink

  • *
  • Posts: 2545
I had a quick look with the built in .svg library and it looks to be worse at rendering than the one I used (which could be newer - I'm unsure now). For a comparison, attached is how the tank is rendered using the built in library (I have yet to experiment extensively).

(Note how the lines go out of the shape they are contained in. Perhaps this is an extreme case - I am unsure
~Letmethink

letmethink

  • *
  • Posts: 2545
To add to this, the stroke definitely has a flat cap and no curve on the edge of the shape (but the built in svg is rendering a curve):
~Letmethink

SadiQ

  • Posts: 1795
I remember trying this with haxe (outside Stencyl) in FlashDevelop and it failed, therefore I never even bothered to try with Stencyl. I wanted to see if this could be applied to backgrounds, but I guess it could be applied to actors as well now, and it would greatly benefit scaling (if the framerate doesn't go down the drain).
Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

PixylWorld

  • Posts: 71
Excellent. It's great to see vector graphics working well in Stencyl. Everyone in the community will appreciate this!

Hectate

  • *
  • Posts: 4643
Since this was bumped recently and I took a look at the embedded "game" I noticed a peculiar behavior. Anything that is (presumably) a stroke is being scaled by the X axis movement, but not Y movement. The horizontal treads are most noticeable for this, since you can see their spacing change easily when moving vertically, but they don't thin/thicken unless you move horizontally as well. It might be a bug in the implementation, or perhaps the SVG engine itself. Presumably the safe fix is to convert all strokes to shapes before utilizing in a game form so that the points of a shape are being scaled, rather than a "line thickness" property.
:
:
Patience is a Virtue,
But Haste is my Life.
Proud member of the League of Idiotic Stencylers; doing things in Stencyl that probably shouldn't be done.

Hectate

  • *
  • Posts: 4643
Figured out the bug on the line rendering scale. The wrong Matrix property was being scaled. The Matrix documentation states that a and c are for the X axis and b and d are for the Y axis, but the render was using a combination of Matrix.a and Matrix.c for scaling line thickness.

If you look up SVGRenderer.hx find the following line (around 137, a search for "m.c" finds it quickly)
Code: [Select]
var scale = Math.sqrt(m.a*m.a + m.c*m.c);
and replace it with:
Code: [Select]
var scale = Math.sqrt(m.a*m.a + m.d*m.d);
Now, this still comes with some caveats. Specifically, the matrix doesn't scale correctly if you are only changing one axis. This is because line thickness is scaled equal across the entire line no matter what orientation(s) the line happens to be.
If you scale in both directions equally (maintaining aspect ratio, essentially), then the thickness will adjust accordingly. As noted in my previous post, you can also just convert your lines to shapes and have it handle them as non-line objects safely.

I'll be submitting a pull request to update the github version with this little tweak, but if you're actively working with it it might be worth modifying your own copy.
I note that I modified the one that was pre-included with Stencyl, however old it is.
:
:
Patience is a Virtue,
But Haste is my Life.
Proud member of the League of Idiotic Stencylers; doing things in Stencyl that probably shouldn't be done.

Hectate

  • *
  • Posts: 4643
<a href="http://static.stencyl.com/games/32714-0.swf" target="_blank" class="new_win">http://static.stencyl.com/games/32714-0.swf</a>
Background and scaling objects are both SVG files. Seems like it's time for more experimentation...
:
:
Patience is a Virtue,
But Haste is my Life.
Proud member of the League of Idiotic Stencylers; doing things in Stencyl that probably shouldn't be done.