Jump to content
  • Advertisement
Sign in to follow this  

SVG and matrices

This topic is 3797 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am trying to implement some support for SVG in my game, actually it will only support rectangles as that's all i need. Anyways, I don't really understand matrices so I'm probably doing something terribly wrong. Anyways, this is the relevant code:
	float x, y, height, width, opacity;
	if (rect->QueryFloatAttribute("x", &x) != TIXML_SUCCESS)
	if (rect->QueryFloatAttribute("y", &y) != TIXML_SUCCESS)
	if (rect->QueryFloatAttribute("width", &width) != TIXML_SUCCESS)
	if (rect->QueryFloatAttribute("height", &height) != TIXML_SUCCESS)
	if (rect->QueryFloatAttribute("opacity", &opacity) != TIXML_SUCCESS)
		opacity = 0.5;

	boost::numeric::ublas::vector<float> bottom_left(3);
	// Assign x
	bottom_left[0] = x;
	// Assign y
	bottom_left[1] = y;
	// Assign z
	bottom_left[2] = 0.0;
	boost::numeric::ublas::vector<float> bottom_right(3);
	bottom_right[0] = x + width;
	bottom_right[1] = y;
	bottom_right[2] = 0.0;
	boost::numeric::ublas::vector<float> top_left(3);
	top_left[0] = x;
	top_left[1] = y + height;
	top_left[2] = 0.0;
	boost::numeric::ublas::vector<float> top_right(3);
	top_right[0] = x + width;
	top_right[1] = y + height;
	top_right[2] = 0.0;
	// transform may or may not exist
	const char * transform = rect->Attribute("transform");
	if (transform)
		using boost::numeric::ublas::column_major;
		boost::numeric::ublas::matrix<float> matrix(3, 3);
		bool full = boost::spirit::parse(transform,
		( // begin grammar
			str_p("matrix(") >> real_p[ assign_a( matrix(0, 0) ) ] >> *ch_p(',') >> real_p[ assign_a( matrix(1, 0) ) ] >> *ch_p(',') >> real_p[ assign_a( matrix(0, 1) ) ] >> *ch_p(',') >> real_p[ assign_a( matrix(1, 1) ) ] >> *ch_p(',') >> real_p[ assign_a( matrix(0, 2) ) ] >> *ch_p(',') >> real_p[ assign_a( matrix(1, 2) ) ] >> ch_p(')')
		), // end grammar
		if (!full)

		matrix(2, 0) = 0;
		matrix(2, 1) = 0;
		matrix(2, 2) = 1;
		bottom_left = boost::numeric::ublas::prod(matrix, bottom_left);
		bottom_right = boost::numeric::ublas::prod(matrix, bottom_right);
		top_left = boost::numeric::ublas::prod(matrix, top_left);
		top_right = boost::numeric::ublas::prod(matrix, top_right);
		bottom_left = boost::numeric::ublas::prod(bottom_left, matrix);
		bottom_right = boost::numeric::ublas::prod(bottom_right, matrix);
		top_left = boost::numeric::ublas::prod(top_left, matrix);
		top_right = boost::numeric::ublas::prod(top_right, matrix);
	boost::shared_ptr<Rectangle> rectangle(new Rectangle);
	rectangle->bottom_left = toVec2(bottom_left);
	rectangle->bottom_right = toVec2(bottom_right);
	rectangle->top_left = toVec2(top_left);
	rectangle->top_right = toVec2(top_right);

I'm using boost::spirit and boost::matrix and boost::vector and TinyXML. This is how it currently looks in my engine: Free Image Hosting at www.ImageShack.us And this is how it should look: Free Image Hosting at www.ImageShack.us Note: Color is not implemented yet. The relevant svg spec about matrices is here: http://www.w3.org/TR/SVG11/coords.html#TransformMatrixDefined The used .svg file is here: http://rafb.net/p/zMYK1889.html As you can see the rectangles that doesn't use matrices look correct but those who does looks wrong. (My matrix math is probably wrong) EDIT: Um, i changed the z coord of the start vectors to 1.0 and it seems to look okay but the .svg is flipped upside down. And clues? EDIT2: I have the same base .svg orginally exported from Illustrator instead of Inkscape and it still doesn't look correct: Free Image Hosting at www.ImageShack.us Svg is here: http://rafb.net/p/MuGjZL59.html [Edited by - lexs on May 28, 2008 2:59:22 PM]

Share this post

Link to post
Share on other sites
If it's flipped upside down, you're probably just using the wrong coordinate system. Just flip the Y-axis. And yes, the 'Z' coordinates do need to be set to 1, otherwise the coordinates do not get translated, only rotated.

Share this post

Link to post
Share on other sites
It renders correctly now (I was not aware that the svg spec didn't require x and y coords).
But it's still upside down. Simply flipping the Y will give wrong results:

Free Image Hosting at www.ImageShack.us

This image is how it looks now, with the green dot being (0,0) in the svg image. It is correctly situated and the lower left corner. If I flip the Y axis it will instead be in the top left corner.

Share this post

Link to post
Share on other sites
Then maybe you're reading the matrix wrong. Try placing an object that's not rotated by 45 degrees into the SVG. E.g. rotate by 25 degrees. If it renders at a wrong angle, then you're reading the elements of the matrix into incorrect locations.

Share this post

Link to post
Share on other sites
Made a .svg with two rectangles rotated by 25 deg and -25 deg:

Free Image Hosting at www.ImageShack.us

Seems to render correctly, just upside down :)

Share this post

Link to post
Share on other sites
So only the rectangles are upside down, even the ones that don't have the transform attribute? But the green dot isn't? How does the SVG differ for the two?

Share this post

Link to post
Share on other sites
Yeah. The dot I render manually. I think I have something wrong in my Rect->VBO code (not posted). Will check it and report back ;)

Share this post

Link to post
Share on other sites
Damn, you were right from the beginning. The origin in SVG is top left so flipping Y is correct.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!