Material, friction and a complete idiot with physics.

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Material, friction and a complete idiot with physics.

Postby cal » Tue Aug 25, 2009 7:01 am

Hi all.

Version:

Newton 1.53, using the OgreNewt rapper for Ogre applications.

Overview:

As the only developer in our very very small company, I've been left with the job of implementing physics in the application we're developing. This application is not a game. Its an application to display other applications, on small rectangular panels, content is not important, but each of these panels are modelled with rigid bodies (boxes). Any time the mouse is clicked on the screen Im modelling it as another rigid body, a cylinder which extends from the viewport down into the scene. This cylinder has large mass compared to the panels. I can move this cylinder with the mouse by modelling its force as a spring with viscous drag. Its slightly laggy at the moment, but moves pretty much as inteded.

Problem:

Im trying to make the cylinder objects interact with the scene. For the most part (when hitting panels from the side) this works fine. However, when the cylinder lands on an object, I cant seem to make it move as intended. The panel should ALWAYS be underneath the cylinder mouse object, but I cant seem to set enough friction to move it. Imagine it like putting your finger on a piece of paper, and dragging it across the table, thats the effect Im going for.

Attempts:

I've tried numerous things, setting high friction between the cylinder mouse object and the panels, and low friction between the panels and the floor. So far the closest I've came to making this work, is to set the velocities in the materials contact callback, simply setting the velocity of the panel to that of the cylinder. This of course is a hack, and it doesn't rotate correctly. It also wont work with multiple mice (we have a multiple mouse setup, its educational software using a promethean style board with multiple pen input), anything after the first interaction does nothing, velocity is always set by the first.

What help I need:

If anyone could offer an example of how to do this, it would be greatly appreciated. As I mentioned above, I want the interaction to model putting your finger on a piece of paper and moving it, the paper will be *stuck* to the bottom of your finger, and rotate / move depending on where you touch it.

Tried to make this post as coherent as possible, if you need any more info just ask. Unfortunately Im not a physics man, so its taking longer than I have to try to get my head around all this.

Thanks in advance, cal.
cal
 
Posts: 3
Joined: Tue Aug 25, 2009 6:46 am

Re: Material, friction and a complete idiot with physics.

Postby JernejL » Tue Aug 25, 2009 8:23 am

The boxes also interact with ground, you should set very low friction for that so it won't interfere with the cylinder dragging.

edit: noticed you already did that, in that case i could suggest you try using a specialized joint or with simple spring physics..
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1578
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: Material, friction and a complete idiot with physics.

Postby cal » Wed Aug 26, 2009 7:14 am

Cheers for the reply delfi.

Yeah I've tried setting low friction between the panels and the floor, but to no avail. The cylinder object still just slides off, which is unfortunate. Giving it a much higher mass improves it, but setting the mass too high makes the cylinder actually push the panels through the floor.

I've decided then to split the interactions out into two distinct cases. Case1, the mouse / pen touch doesn't hit a panel, and so a cylinder is created which then slides along the floor, and interacts with panels as expected. Case2, the mouse / pen touch hits a panel, in which case Im setting the forces on the panel directly as I do on the cylinder. This works, with one minor issue. I dont know how to make the panels rotate from the force.

My custom force feedback uses the following code.

Code: Select all
      // get the position and rotation of the newton object, m_body
      Ogre::Vector3 pos;
      Ogre::Quaternion rot;
      m_body->getPositionOrientation(pos, rot);

      // _Marker is a class to handle the multiple mouse / pen touches. Stores position, id, last position and
      // a couple extras.
      size_t i;
      for(i=0; i<m_markers->size(); i++)
      {
         _Marker *marker = m_markers->at(i);

         // time just saves on updates. Was previously used to prevent a divide by zero, but that issues now gone.
         if(marker->i_time > 0)
         {
            // get the distance the mouse / pen has moved
            Ogre::Vector3 dist(marker->i_worldPos-marker->i_lastWorldPos);
            // get the current velocity of our panel
            Ogre::Vector3 vel = m_body->getVelocity();

            Ogre::Real k = 1500;
            Ogre::Real c = 40;
            // set a spring force with a viscous drag to make the panel follow our mouse / pen nicely
            Ogre::Vector3 force((k* dist.x) - (c* vel.x), 0,(k* dist.z) - (c* vel.z));
            // add the force to the object
            m_body->addForce(force);

            // add some force to make it rotate? this is the bit Im stuck on.
            
            


            // reset the time -- its updated per frame
            marker->i_time = 0;

            // reset the position of the marker
            marker->i_lastWorldPos = marker->i_worldPos;
         }
      
      }

      Ogre::Real mass;
      Ogre::Vector3 inertia;
      m_body->getMassMatrix(mass, inertia);

      // add gravity
      m_body->addForce(Ogre::Vector3(0,-9.8*mass, 0));
   
cal
 
Posts: 3
Joined: Tue Aug 25, 2009 6:46 am

Re: Material, friction and a complete idiot with physics.

Postby JernejL » Wed Aug 26, 2009 9:06 am

cal wrote: This works, with one minor issue. I dont know how to make the panels rotate from the force.


You just need to apply the force in local space - transformed by the body matrix to take transformation into account - from the dragging start origin. I have some delphi code home which does this (addlocalforce & addglobalforce), i'll post them once i come back home.
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1578
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: Material, friction and a complete idiot with physics.

Postby JernejL » Wed Aug 26, 2009 12:32 pm

Ok here are the functions, several others useful ones too.. i really wish this functionality would be part of newton itself, it would save people a lot of hassle when they want to control bodies by applying a force at a certain point on them.

Code: Select all
// retrieves body's velocity at specific point in global space
function GetPointGlobalVelocity(const body: PNewtonBody; Point: Vector): Vector;
var
  velocity, omega: Vector;
begin
  NewtonBodyGetVelocity(body, @velocity);
  NewtonBodyGetOmega(body, @omega);

  Result := AddVectors(velocity, crossProduct(omega, point));
end;

// retrieves body's velocity at specific point in local space
function GetPointLocalVelocity(const body: PNewtonBody; Point: Vector): Vector;
var
  bodymatrix: Tmatrix4F;
begin
  NewtonBodyGetMatrix(body, @bodymatrix);
  Result := GetPointGlobalVelocity(body, MatrixRotateVector(Point, bodymatrix));
  Result := MatrixUNRotateVector(Result, bodymatrix);
end;

// adds force to body at a specified point in global space
procedure AddPointGlobalForce(const body: PNewtonBody; PrevBodyMatrix: pointer; Force, Point: Vector);
var
  GlobalForce: vector;
  bodymatrix:  Tmatrix4F;
  Torque:      vector;
begin

  if PrevBodyMatrix = nil then
    NewtonBodyGetMatrix(body, @bodymatrix)
  else
    move(PrevBodyMatrix^, bodymatrix, sizeof(Tmatrix4F));

  GlobalForce.x := Point.x - bodymatrix[3][0];
  GlobalForce.y := Point.y - bodymatrix[3][1];
  GlobalForce.z := Point.z - bodymatrix[3][2];

  Torque := CrossProduct(GlobalForce, Force);

  NewtonBodyAddForce(body, @Force.x);
  NewtonBodyAddTorque(body, @Torque.x);
end;


// adds force to body at a specified point in local space
procedure AddPointLocalForce(const body: PNewtonBody; Force, Point: Vector);
var
  GlobalForce, GlobalPoint: Vector;
  bodymatrix: Tmatrix4F;
begin
  NewtonBodyGetMatrix(body, @bodymatrix);

  GlobalForce := MatrixRotateVector(Force, bodymatrix);
  GlobalPoint := MatrixTransformVector(Point, bodymatrix);

  AddPointGlobalForce(body, @bodymatrix, GlobalForce, GlobalPoint);
end;
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1578
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: Material, friction and a complete idiot with physics.

Postby cal » Fri Sep 11, 2009 7:22 am

Ok, finally gotten time to come back to this.

Delfi, I tried the functions you provided, but the behaviour was erratic. I've tried to figure out why, but I have to admit, Im way over my head with this stuff. I asked a mate who knows physics, and he gave me a couple other functions which allow me to directly move the panels with a spring effect on movement, and a torque to spin them. It seems to just spin way too much though, i can lower a coefficient, but the difficulties are now making me think I should take another direction.

I've now been advised to go with joints, but Im somewhat losing the motivation for this. If somebody could give me some advice on setting up a joint that can attach from the cylinder object (projects from camera to scene) to the panel it would be greatly appreciated. This joint would have to be able to rotate around the y axis (normal to the panel) but shouldnt rotate in any other axis. I've set the cylinder so that shouldnt rotate.
cal
 
Posts: 3
Joined: Tue Aug 25, 2009 6:46 am


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 9 guests

cron