Sign in to follow this  
Finalspace

Unique results in a physics engine

Recommended Posts

First of all i am not sure if coding horror fits this, but the results from my implementation of a rigid body physics system is very unique, check it out. There may be some deep critters hiding in the code...
 
https://www.youtube.com/watch?v=r7rmuB0H1Is
 
...NOT, it was just three classics:
 
1.) vec2 * mat2 is not the same as mat2 * vec2
Rotate left against rotate right. -> contacts was wrong rotated.
 
2.) Cross(1.0f, normal) is not the same as Cross(normal, 1.0f).
Same as above, inverted rotation...
 
3.) There was always a friction impulse going on, even with friction set to zero.
A classic wrong arguments orders bug: Clamp(min, value, max) is not the same as Clamp(value, min, max) and i had:
 
contact->tangentImpulse = Clamp(oldTangentImpulse + tangentImpulse, -maxFriction, maxFriction);

Lessons learned:

- Porting from own old sources should never be underestimated, especially when there was no operator overload used or supported!
- Check your math library before doing any useful with that, especially matrices and rotations. Make Units tests or something... Edited by Finalspace

Share this post


Link to post
Share on other sites

First of all i am not sure if coding horror fits this, but the results from my implementation of a rigid body physics system is very unique, check it out. There may be some deep critters hiding in the code...
 
https://www.youtube.com/watch?v=r7rmuB0H1Is
 
...NOT, it was just three classics:
 
1.) vec2 * mat2 is not the same as mat2 * vec2 in "openGL mathematics".
Rotate left against rotate right. -> contacts was wrong rotated.
 
2.) Cross(1.0f, normal) is not the same as Cross(normal, 1.0f).
Same as above, inverted rotation...
 
3.) There was always a friction impulse going on, even with friction set to zero.
A classic wrong arguments orders bug: Clamp(min, value, max) is not the same as Clamp(value, min, max) and i had:
 
contact->tangentImpulse = Clamp(oldTangentImpulse + tangentImpulse, -maxFriction, maxFriction);

Lessons learned:

- Porting from own old sources should never be underestimated, especially when there was no operator overload used or supported!
- Check your math library before doing any useful with that, especially matrices and rotations. Make Units tests or something...

 

Uhm... M * v and v * M are never the same (for general matrices) not only in "OpenGL mathematics", but in linear algebra in general...

Edited by l0calh05t

Share this post


Link to post
Share on other sites

Uhm... M * v and v * M are never the same (for general matrices) not only in "OpenGL mathematics", but in linear algebra in general...


I dont know, i never learned linear algebra but i know that A times B is the same as B times A (True for scalars and vectors, commutative property of multiplication right?).
 
inline Vec2f operator *(const Vec2f &a, const Mat2f &mat)
{
	Vec2f result;
	result.x = mat.col1.x * a.x + mat.col2.x * a.y;
	result.y = mat.col1.y * a.x + mat.col2.y * a.y;
	return(result);
}
This multiplies a vector and a matrix and looking at the code, it does not matter in which order it is.

Edit: I double checked the glm implementation and its just transposed vs non-transposed Matrix multiplication (row vs col):
 
	template <typename T, precision P>
	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::col_type operator*
	(
		tmat2x2<T, P> const & m,
		typename tmat2x2<T, P>::row_type const & v
	)
	{
		return tvec2<T, P>(
			m[0][0] * v.x + m[1][0] * v.y,
			m[0][1] * v.x + m[1][1] * v.y);
	}

	template <typename T, precision P>
	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::row_type operator*
	(
		typename tmat2x2<T, P>::col_type const & v,
		tmat2x2<T, P> const & m
	)
	{
		return tvec2<T, P>(
			v.x * m[0][0] + v.y * m[0][1],
			v.x * m[1][0] + v.y * m[1][1]);
	}

PS: Sorry for the edits...

Does this imply that in math formulas when i see m * v it always mean column based multiplication and v * m means row based???

I really should learn linear algebra. Edited by Finalspace

Share this post


Link to post
Share on other sites

 

Uhm... M * v and v * M are never the same (for general matrices) not only in "OpenGL mathematics", but in linear algebra in general...


I dont know, i never learned linear algebra but i know that A times B is the same as B times A (True for scalars and vectors, commutative property of multiplication right?).
 
inline Vec2f operator *(const Vec2f &a, const Mat2f &mat)
{
	Vec2f result;
	result.x = mat.col1.x * a.x + mat.col2.x * a.y;
	result.y = mat.col1.y * a.x + mat.col2.y * a.y;
	return(result);
}
This multiplies a vector and a matrix and looking at the code, it does not matter in which order it is.

Edit: I double checked the glm implementation and its just transposed vs non-transposed Matrix multiplication (row vs col):
 
	template <typename T, precision P>
	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::col_type operator*
	(
		tmat2x2<T, P> const & m,
		typename tmat2x2<T, P>::row_type const & v
	)
	{
		return tvec2<T, P>(
			m[0][0] * v.x + m[1][0] * v.y,
			m[0][1] * v.x + m[1][1] * v.y);
	}

	template <typename T, precision P>
	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::row_type operator*
	(
		typename tmat2x2<T, P>::col_type const & v,
		tmat2x2<T, P> const & m
	)
	{
		return tvec2<T, P>(
			v.x * m[0][0] + v.y * m[0][1],
			v.x * m[1][0] + v.y * m[1][1]);
	}

PS: Sorry for the edits...

Does this imply that in math formulas when i see m * v it always mean column based multiplication and v * m means row based???

I really should learn linear algebra.

 

 

Nope, matrix multiplication (including matrix-vector multiplication) is non-commutative. Dot products are commutative though, but cross products on the other hand are anti-commutative.

 

Mv implies that v is a column vector, vM implies that v is a row vector (the latter notation is extremely rare in mathematics textbooks and is pretty much exclusive to computer graphics nowadays)

 

And yes, understanding linear algebra is extremely important in computer graphics (and physics)

Edited by l0calh05t

Share this post


Link to post
Share on other sites

Since all matrix operations comprise of row dot column, there is actually not such thing as a vector * matrix, because there is no such meaningful operation that consists of a column vector dotted with a row vector. The result of this operation would be the following: 

| a |  *  | x y z |  =  | ax ay az |  
| b |                   | bx by bz |
| c |                   | cx cy cz |

And this operation (from my basic understanding) has no benefit/purpose in the field of linear algebraic studies.

Edited by fais

Share this post


Link to post
Share on other sites

Since all matrix operations comprise of row dot column, there is actually not such thing as a vector * matrix, because there is no such meaningful operation that consists of a column vector dotted with a row vector. The result of this operation would be the following: 

| a |  *  | x y z |  =  | ax ay az |  
| b |                   | bx by bz |
| c |                   | cx cy cz |
And this operation (from my basic understanding) has no benefit/purpose in the field of linear algebraic studies.


Maybe you need to do more linear algebra studying. https://en.wikipedia.org/wiki/Outer_product

Edit: So far I've used the out product to project vectors onto planes, during vector calculus involving springs, and in inertia tensor calculations for triangle meshes. Edited by Randy Gaul

Share this post


Link to post
Share on other sites

Since all matrix operations comprise of row dot column, there is actually not such thing as a vector * matrix, because there is no such meaningful operation that consists of a column vector dotted with a row vector. The result of this operation would be the following:

| a |  *  | x y z |  =  | ax ay az |  | b |                   | bx by bz || c |                   | cx cy cz |
And this operation (from my basic understanding) has no benefit/purpose in the field of linear algebraic studies.
Maybe you need to do more linear algebra studying. https://en.wikipedia.org/wiki/Outer_productEdit: So far I've used the out product to project vectors onto planes, during vector calculus involving springs, and in inertia tensor calculations for triangle meshes.
Thank you for that. As I said my knowledge regarding Lin Al and the operation is very rudimentary. Surprisingly, it was my physics professor back in 2005 who described it as a rather pointless operation. I suspected otherwise, happy I was wrong l, and I'm actually excited to read up on it now.

To add to this, a vector * matrix still is an invalid operation due to dimensional mismatch.

Share this post


Link to post
Share on other sites
On a somewhat related note I always thought it would be fun to write alternate physics engines that have consistent rules that aren't realistic but give more cartoonish results such as fast moving objects aren't effected by gravity. Don't have newtons 3rd law but make the more massive or fast moving object be unaffected by what it hits, think of a cartoon character being hit by a cannon ball. The ability to build up momentum in place then release it all at once. It would probably have some huge stability issues in the physics simulation but rules can be added as needed to stabilize without losing the cartoon feel of the engine.

Share this post


Link to post
Share on other sites

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