I am trying to define the following callback from Nim: 
    
    
    static void nearCallback (void *data, dGeomID o1, dGeomID o2)
    {
      int i;
      
      //-- Get the body's ID
      dBodyID b1 = dGeomGetBody(o1);
      dBodyID b2 = dGeomGetBody(o2);
      
      //-- If they are connected by a joint, no collision detection is done. 
Finish
      if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact)) {
        return;
      }
      
      //-- Configure the properties for the contact points
      dContact contact[MAX_CONTACTS];
      for (i=0; i<MAX_CONTACTS; i++) {
        contact[i].surface.mode = dContactBounce | dContactSoftCFM;
        contact[i].surface.mu = MU;
        contact[i].surface.mu2 = MU2;
        contact[i].surface.bounce = BOUNCE;
        contact[i].surface.bounce_vel = BOUNCE_VEL;
        contact[i].surface.soft_cfm = SOFT_CFM;
      
      }
      
      //-- Get the contact points
      int numc = dCollide (o1,o2,MAX_CONTACTS,&contact[0].geom, 
sizeof(dContact));
      
      //-- If there are at least one contact point...
      if (numc!=0) {
        
        //-- For every contact point a joint should be created
        for (i=0; i<numc; i++) {
          
          //-- Create the joint and add it to the contact group
          dJointID c = dJointCreateContact (world,contactgroup,&contact[i]);
          
          //-- Set the articulation between the two bodies
          dJointAttach (c,b1,b2);
        }
      }
    }
    
    
    Run

In the C example, both world and contactgroup are global.

I tried to define this callback using a closure like this: 
    
    
    proc genNearCallBack(world:dWorldID, 
contactgroup:dJointGroupID):dNearCallback =
      let world = world
      let contactgroup = contactgroup
      return proc( data:pointer, o1,o2:dGeomID) {.exportc,cdecl.} =
        #[
        Callback function invoked by the dSpaceCollide function when two objects
        are about to collide
        The contact points should be found and a special contact joints should 
be
        added. After that simulation step, the contact joints should be removed
        ]#
        # Get the body's ID
        var b1 = dGeomGetBody(o1)
        var b2 = dGeomGetBody(o2)
        
        # If they are connected by a joint, no collision detection is done. 
Finish
        if b1 != nil and b2 != nil and 
(dAreConnectedExcluding(b1,b2,dJointTypeContact.cint) == 1):
          discard ""
        else:
          # Configure the properties for the contact points
          var contact = newSeq[dContact]( MAX_CONTACTS )
          for i in 0..<MAX_CONTACTS:
            contact[i].surface.mode = dContactBounce.cint + 
dContactSoftCFM.cint  #dContactBounce | dContactSoftCFM
            contact[i].surface.mu = MU
            contact[i].surface.mu2 = MU2
            contact[i].surface.bounce = BOUNCE
            contact[i].surface.bounce_vel = BOUNCE_VEL
            contact[i].surface.soft_cfm = SOFT_CFM
          
          # Get the contact points
          let numc = dCollide(o1, o2, MAX_CONTACTS, contact[0].geom.unsafeAddr, 
sizeof(dContact).cint)
          
          # If there are at least one contact point...
          if numc != 0:
            # For every contact point a joint should be created
            for i in 0..<numc:
              # Create the joint and add it to the contact group
              var c = 
dJointCreateContact(world,contactgroup,contact[i].unsafeAddr)
              
              # Set the articulation between the two bodies
              dJointAttach(c,b1,b2)
    
    
    Run

and I am getting the mentioned error: 
    
    
    Error: illegal capture 'world' because ':anonymous' has the calling 
convention: <cdecl>
    
    
    Run

It is simply not possible or to do it because of the calling convention or is 
it that I am not doing the closure properly?

Cheers

Reply via email to