[solved] [MogreNewt] Strange behaviour


10-10-2007 00:20:59

Please, somebody can tell to me why after collision with object "_floor" the object "_body" departs in an opposite direction?

Just run my code (windows form project, designed part of MainForm class contains only Panel named "panDisplay")

public partial class MainForm : Form
private Graphics _graphics = null;
private int _screenWidth = 0;
private int _screenHeight = 0;

private World _world = null;
private Body _body = null;
private Body _floor = null;
private System.Windows.Forms.Timer _timer = null;

public MainForm()

_graphics = panDisplay.CreateGraphics();
_screenHeight = panDisplay.Height;
_screenWidth = panDisplay.Width;


_timer = new System.Windows.Forms.Timer();
_timer.Interval = 100;
_timer.Tick += new EventHandler(_timer_Tick);

private void InitScene()
_world = new World();

private void InitMaterials()
MaterialID def = _world.DefaultMaterialID;
MaterialPair material = new MaterialPair(_world, def, def);
material.SetDefaultFriction(1.0f, 0.5f);

private void CreateFloor()
float mass = 100.0f;
Vector3 size = new Vector3(0.9f, 0.1f, 0.9f);
Vector3 inertia = MomentOfInertia.CalcBoxSolid(mass, size);

MogreNewt.CollisionPrimitives.Box collision = new MogreNewt.CollisionPrimitives.Box(_world, size);

_floor = new Body(_world, collision);

//_floor.SetMassMatrix(mass, inertia);
Quaternion orientation = new Quaternion(new Degree(45.0f), Vector3.UNIT_Z);
_floor.MaterialGroupID = _world.DefaultMaterialID;
_floor.SetPositionOrientation(new Vector3(0.5f, 0.3f, 0.0f), orientation);


private void CreateSphere()
float mass = 1.0f;
Vector3 size = new Vector3(0.05f, 0.05f, 0.05f);
Vector3 inertia = MomentOfInertia.CalcEllipsoidSolid(mass, size);
MogreNewt.CollisionPrimitives.Ellipsoid collision = new MogreNewt.CollisionPrimitives.Ellipsoid(_world, size);
_body = new Body(_world, collision);

_body.SetMassMatrix(mass, inertia);
_body.MaterialGroupID = _world.DefaultMaterialID;
_body.SetPositionOrientation(new Vector3(0.5f, 0.9f, 0), Quaternion.IDENTITY);
_body.ForceCallback += new ForceCallbackHandler(body_ForceCallback);

void _timer_Tick(object sender, EventArgs e)



void body_ForceCallback(Body body)
body.AddForce(new Vector3(0, -1f * body.Mass, 0));

private void DrawBody(Body sender)
Pen p = new Pen(Color.Red, 1);
Matrix3 rotation = sender.Orientation.ToRotationMatrix();

Vector3[] corners = sender.Collision.AABB.GetAllCorners();
PointF last = PointF.Empty;
foreach (Vector3 corner in corners)
Vector3 rotated = corner * rotation + sender.Position;
PointF screen = new PointF();
screen.X = rotated.x * _screenWidth - 2;
screen.Y = (1 - rotated.y) * _screenHeight - 2;

_graphics.DrawEllipse(p, new RectangleF(screen, new Size(2, 2)));
if (last != PointF.Empty)
_graphics.DrawLine(p, last, screen);
last = screen;

private void MainForm_Load(object sender, EventArgs e)

Tnx a lot, and sorry if my question is too simple - i am new :)


10-10-2007 04:22:54

Hi there!

Nice little demo there. Good idea to test your stuff without going full 3D at first. Here everything seem to work fine as far as physics goes. The sphere (which is drawn as an AABB) bounces on the ramp and eventually falls off the screen.

The only problem I see is that everything is drawn backward! It is a very little mistake. When you compute the screen position of the corner, you actually do a matrix pre-multiplication instead of post-multiplication. In short, you are applying the inverse rotation. To fix, change :
Vector3 rotated = corner * rotation + sender.Position;
Vector3 rotated = rotation * corner + sender.Position;

Hope it helps.



10-10-2007 13:50:37

Big thanks! Realy, It was my mistake :)