Sign in to follow this  

SVG and matrices

This topic is 3488 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)
		return;
		
	if (rect->QueryFloatAttribute("y", &y) != TIXML_SUCCESS)
		return;
		
	if (rect->QueryFloatAttribute("width", &width) != TIXML_SUCCESS)
		return;
		
	if (rect->QueryFloatAttribute("height", &height) != TIXML_SUCCESS)
		return;
		
	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
		boost::spirit::space_p).full;
		
		if (!full)
			return;

		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);
	
	rectangles.push_back(rectangle);





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
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

This topic is 3488 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this