Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Irrlicht and Newton ConvexHull

  1. #1

    Irrlicht and Newton ConvexHull

    Hi there, long time no see, looking for a little help, i am currently using Irrlicht 1.71 and Newton 2.29. i have so far got everything working apart from convex hull objects, i read that newton and irrlicht both use different sizes, i have fiddled around trying to get it to work with no luck, it "kind of" works, anyways this is my code for creating the collision hull

    Code:
    function CreateConvexHullCollisionFromMesh(nWorld: PNewtonWorld; node: ISceneNode; irr_mesh: IMesh): PNewtonCollision;
    var
      nMeshBuffer       : Integer; //Mesh Buffer count
      nVertices         : LongWord;
      mesh_buffer       : IMeshBuffer;
      tCounter          : LongWord;
      vertices          : array of Vector3df;
      _vertices         : PS3DVertex;
      i                 : Integer;
    begin
      nMeshBuffer := 0;
      nVertices := 0;
    
      //get number of vertices
      for nMeshBuffer := 0 to irr_mesh.getMeshBufferCount() - 1 do begin
        nVertices := nVertices + irr_mesh.getMeshBuffer(nMeshBuffer).getVertexCount();
      end;
    
      //create buffer for vertices
      SetLength(vertices, nVertices);
      tCounter := 0;
    
      //get (irr_)mesh buffers and copy face vertices
      for nMeshBuffer := 0 to irr_mesh.getMeshBufferCount() - 1 do begin
        mesh_buffer := irr_mesh.getMeshBuffer(nMeshBuffer);
    
        //get pointer to vertices and indices
        _vertices := PS3DVertex(mesh_buffer.getVertices());
    
        {$POINTERMATH ON}
        //copy vertices from mesh to buffer
        for i := 0 to mesh_buffer.getVertexCount() - 1 do begin
          vertices[tCounter].x := _vertices[i].Pos.x;
          vertices[tCounter].y := _vertices[i].Pos.y;
          vertices[tCounter].z := _vertices[i].Pos.z;
    
          Inc(tCounter);
        end;
        {$POINTERMATH OFF}
      end;
    
      //Create Newton collision object
      Result := NewtonCreateConvexHull(nWorld, nVertices, @vertices[0].x, sizeof(vector3df), 0, 0, nil);
    
      //remove from mem space
      vertices := nil;
    end;
    currently i have tried with several objects, i am loading it with a cube just to test with... what happens is the cube falls, hits the ground, then gradually (slowly) falls through and then off it goes falling to bottom of newton world size. im guessing my ground is fine since creating newtonbox works just fine, all physics work for this with many objects, 1000s even, just not the convex hull, hope you can help, thanks.
    Last edited by Colin; 17-01-2011 at 01:48 PM.

  2. #2
    Could you please post the rest of the code for creating the actual newton body from the collider? The code above looks correct, so the problem must be caused somewhere else. And if your body acts weird it's often down to a wrong mass / inertia matrix, so that code would be interesting to see. And did you add debug display functionality to see if the hull is actually correct? Maybe it's not the mass / inertia but wrongly assigned vertices or a wrong shape (is your object really convex, and doesn't have holes etc.), so a visual display of what newton actually uses as the shape for convex hull is also very useful.

  3. #3
    I don't know either of these libraries, but how do they define faces? Are they Triangles, Triangle_strip or something else, maybe custom?

    This is because just vertex alone is not enough to define collision for physics. You can have 1 small triangle and 1 large triangle and if the small one falls on top of the large one it shouldn't go through.

  4. #4

    Red face

    hi there, thanks for replies, ok so i got up this morning, checked all my libs and realised i had downloaded newton 2.29 but not extracted it .... ok so how silly i am i was still using 2.24 anyways i updated the dll, and now nothing collides correctly, so i moved back to trying to get boxes to collide.

    i found 1 strange thing in my box.init procedure if i change the

    CreateNewtonBody matrix to the const vPosition value i pass to the procedure it creates the boxes and all is drawn correct and seems to work, only everything is created in 1 place, not the values of vPosition_ and the debug seems has larger scale ( i have tried several things to fix with no success)

    if i create from a seperate vector3df then it does not work, draws boxes elsewhere and physics debug is elsewhere also.

    the code:

    debug rendering:
    Code:
    procedure RenderDebugCollision(body: Pointer; vertexCount: Integer; const FaceArray: PFloat; faceId: Integer); cdecl;
    var
      i: Integer;
      p0: Vector3df;
      p1: Vector3df;
      irr_p1: Vector3df;
      irr_p2: Vector3df;
      active: Integer;
      color: PSColorf;
    begin
      active := NewtonBodyGetSleepState(body);
    
      case active of
        0: color := getSColorfp(255,0,255,0); //getSColorfp(255,0,255,0);
        1: color := getSColorfp(255,255,255,0);
      end;
    
      i := vertexcount - 1;
    
      {$POINTERMATH ON}
      p0.x := FaceArray[i * 3 + 0];
      p0.y := FaceArray[i * 3 + 1];
      p0.z := FaceArray[i * 3 + 2];
    
      for i := 0 to vertexcount-1 do begin
        p1.x := FaceArray[i * 3 + 0];
        p1.y := FaceArray[i * 3 + 1];
        p1.z := FaceArray[i * 3 + 2];
    
        Driver.draw3DLine(@p0.x, @p1.x, color.toSColor);
    
        p0 := p1;
      end;
      {$POINTERMATH OFF}
    end;
    
    procedure DebugCallback(const body : PNewtonBody); cdecl;
    var
      m: matrix4;
    begin
      NewtonBodyGetMatrix(body, @m.M[0]);
      NewtonCollisionForEachPolygonDo(NewtonBodyGetCollision(body), @m.M[0], RenderDebugCollision, Pointer(body));
    end;
    the loop

    Code:
      lastFPS := -1;
      while device.run do begin
        driver.beginScene(True, True, getSColor(255, 100, 101, 140), DefEVD, nil);
    
        smgr.drawAll;
        gui.drawAll;
    
        DebugCallback(box1.newtonBody);
        DebugCallback(box2.newtonBody);
        DebugCallback(level.newtonBody);
    
        driver.endScene;
        //  fps
        fps := driver.getFPS;
        if (lastFPS <> fps) then begin
          device.setWindowCaption(PWideChar(WideString('FPS: ' + str(fps))));
          lastFPS := fps;
        end;
    
        NewtonUpdate(nWorld, 1.0 / fps);
        //NewtonUpdate(nWorld, 0.01);
      end;
    before the loop i create my game objects (custom records)

    Code:
        box1.Init(nWorld, smgr, 1, nil, -1, getvector3dfp(0,500,0),getvector3dfp(0,0,0),getvector3dfp(50,50,50), 10);
        setMaterialFlag(box1.node, EMF_LIGHTING, false);
        setMaterialTexture(box1.node, 0, getTexture(driver, 'models/crate.jpg'));
    
        box2.Init(nWorld, smgr, 1, nil, -1, getvector3dfp(0,650,0),getvector3dfp(0,0,0),getvector3dfp(50,50,50), 10);
        setMaterialFlag(box2.node, EMF_LIGHTING, false);
        setMaterialTexture(box2.node, 0, getTexture(driver, 'models/crate.jpg'));
    for now i just made them static records (no pointer) which then does the following:

    Code:
    procedure TBox.Init(nWorld: PNewtonWorld; smgr: ISceneManager; vSize: Single; vParent: PISceneNode; vId: Integer; const vPosition_: Pvector3dF; const vRotation_: Pvector3dF; const vScale_: Pvector3dF; pMass : Single);
    var
      Inertia   : Vector3df;
      Collision : PNewtonCollision;
    
      offset: matrix4;
    begin
      offset.makeIdentity();
      node := smgr.addCubeSceneNode(vSize, vParent, vId, vPosition_,vRotation_,vScale_);
    
      Collision  := NewtonCreateBox(nWorld, vScale_.x, vScale_.y, vScale_.z, 0, offset.pointer);
      // Create the rigid body
      newtonBody := CreateNewtonBody(nWorld, Collision, @vPosition_.x);
      NewtonReleaseCollision(nWorld, Collision);
    
    	NewtonBodySetUserData(newtonBody, node);
    
      Inertia.x := pMass * (vScale_.y * vScale_.y + vScale_.z * vScale_.z) / 12;
      Inertia.y := pMass * (vScale_.x * vScale_.x + vScale_.z * vScale_.z) / 12;
      Inertia.z := pMass * (vScale_.x * vScale_.x + vScale_.y * vScale_.y) / 12;
    
      // Set the bodies mass and moment of inertia
      NewtonBodySetMassMatrix(newtonBody, pMass, Inertia.x, Inertia.y, Inertia.z);
    
      // Finally set the callback in which the forces on this body will be applied
      NewtonBodySetForceAndTorqueCallBack(newtonBody, ForceAndTorqueCallBack);
    	NewtonBodySetTransformCallback(newtonBody, SetTransformCallback);
    end;
    callbacks:
    Code:
    procedure SetTransformCallback(const body: PNewtonBody; const matr: PFloat; threadIndex: Integer); cdecl;
    var
      node: ISceneNode;
      irrMat: matrix4;
      pos: Vector3df;
      rot: Vector3df;
    begin
      node := NewtonBodyGetUserData(body);
    
    	if assigned(node) then begin
        CopyMemory(irrMat.pointer(), matr, sizeof(Float)*16);
    
        pos := irrMat.getTranslation^;
        rot := irrMat.getRotationDegrees();
    
        node.setPosition(@pos.x);
        node.setRotation(@rot.x);
      end;
    end;
    
    
    procedure ForceAndTorqueCallback(const body: PNewtonBody; timestep: float; threadindex: integer); cdecl;
    var
      Mass    : Single;
      Inertia : Vector3df;
      Force   : Vector3df;
    begin
      NewtonBodyGetMassMatrix(body, @Mass, @Inertia.x, @Inertia.y, @Inertia.z);
    
      Force := getvector3df(0, -9.8 * Mass, 0); // earth? :)
      NewtonBodyAddForce(body, @Force.x);
    end;
    example app:

    download here

    thanks hope you can help.


    EDIT:
    note to mods, there seems to be a glitch in [ code] it keeps adding extra tabs to my code.
    Last edited by Colin; 18-01-2011 at 01:20 PM.

  5. #5
    newtonBody := CreateNewtonBody(nWorld, Collision, @vPosition_.x);
    What's behind vPosition_? If it's only a single vector containint the object's position that could be the problem, cause you need to pass a full matrix as the last parameter. And if it doesn't work when passing a matrix make sure the matrix' alignment is same as the alignment newton uses, dunno if Irrlicht uses a different alignment or something. It has to be a correct 4x4 matrix with valid values or troubles will arise.

    Other than that I can't see what's wrong cause you're using a lot of Irrlicht-related stuff and datatypes. Maybe offload everything to a separate app without Irrlicht and try it there again. Or get the basic SDL-demo from my page and take a look at it's source code.

  6. #6
    hi thanks, yes i wrote a directx renderer previously in dx9, added newton and it worked just fine, but now i want to implement it into irrlicht... anyways i think i have solved some of the problems, just having a little trouble with inertia now..
    Last edited by Colin; 18-01-2011 at 04:15 PM.

  7. #7
    Just use NewtonConvexCollisionCalculateInertialMatrix, this function can calculate a correct inertial matrix for you and should work better than calculating it yourself.

  8. #8
    aha, thank you very much, that works great, however there is 1 small thing, is there a way to stop them bouncing so much? makes them look unrealistic, even when i set the mass higher, they still bounce around and look unrealistic, once they start falling and rolling, they look ok, but the bouncing is not good.

    for example download here

    thanks

  9. #9
    Just apply different materials to your objects. Lower the material's softness and change elasticity values to get the object to react like it's heavier.

  10. #10
    aha... thank you , everything now is working absolutly perfect now, thanks alot for the help.

    1 other quick question regarding newton 2.29 does it still have procedure to set the freeze threshold ?

    -Colin
    Last edited by Colin; 18-01-2011 at 09:34 PM.

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •