mesh collisions

djigneodjigneo Posts: 283
edited December 1969 in Daz Script Developer Discussion

Hello,

I'm new to creating DAZ scripts and I'm reading through the API and trying to get a grasp on what's there.

I'm looking for a way to determine if two dzGeometry objects intersect each other, that is: at least one facet from Geometry #1 touches at least one facet from Geometry #2. I was hoping there'd be a function I could just consume in the DAZ API, but after hours of browsing I'm not seeing anything that looks close.

Does such a function exist in the standard API? If not, is there a script example somewhere that already does this / is fairly close that I could study?

Thanks for the help!

Comments

  • rbtwhizrbtwhiz Posts: 2,267
    edited July 2014

    The DAZ Studio scripting API does not provide convenience classes/functions specifically for determining geometry collision/intersection.

    Testing for collisions between the bounding boxes of nodes is fairly simple...

    function collides( boxA, boxB ){
     return !(
      (boxA.maxX < boxB.minX) || (boxA.minX > boxB.maxX) ||
      (boxA.maxY < boxB.minY) || (boxA.minY > boxB.maxY) ||
      (boxA.maxZ < boxB.minZ) || (boxA.minZ > boxB.maxZ)
     );
    };
    
    // Get the selected nodes in the scene
    var aNodes = Scene.getSelectedNodeList();
    // If we have enough nodes to test collision
    if( aNodes.length > 1 ){
     // Declare working variables
     var oNodeA, oNodeB;
     var bCollides;
     var sFeedback;
     // Iterate over the selected nodes
     for( var i = 0; i < aNodes.length; i += 1 ){
      // Get the 'current' node
      oNodeA = aNodes[ i ];
      // Iterate over the selected nodes
      for( var j = 0; j < aNodes.length; j += 1 ){
       // Get the node to check
       oNodeB = aNodes[ j ];
       // If the nodes are the same
       if( pointersAreEqual( oNodeA, oNodeB ) ){
        // Next!
        continue;
       }
    
       // Get whether the world space bounding boxes intersect/collide
       bCollides = collides( oNodeA.getWSBoundingBox(), oNodeB.getWSBoundingBox() );
       // Construct debugging data
       sFeedback = String("'%1' %2 with '%3'")
        .arg( oNodeA.getLabel() )
        .arg( bCollides ? "collides" : "does not collide" )
        .arg( oNodeB.getLabel() );
       // Let's see it...
       print( sFeedback );
      }
     }
    }

    ... but as you can see from the nested loops, its an n^2 problem that can quickly get out of hand. The longer the list, the longer it will take to process. It is for this reason that you'll need to consider/implement an acceleration structure.

    -Rob

    Post edited by rbtwhiz on
  • djigneodjigneo Posts: 283
    edited July 2014

    Thanks for the response! It's good to know I can stop my search for some functions to do the heavy lifting for me.

    I like the tip about the bounding box, it seems like that's a really good first step towards my solution because I can do a very quick check to see if the objects are even close to colliding before falling down to a Facet by Facet comparison.

    Edit: I realize that the bounding box code is intentionally aligned toward world axis because that is indeed what makes it a simple calculation in the first place. Forgive my 3d naivety in the following paragraph.
    There does, however, seem to be an constraint of your code example though. The code seems to assume that the bounding box of the object is always oriented to directly align with the world axis. So, for example, if you create a cylinder and rotate it around X or Z, the bounding box as displayed in the DAZ UI will correctly follow the orientation of the object. Your example doesn't use this aligned bounding box, but rather will get a non-rotated, (but possibly much larger ) box around the object which is aligned with the world axis. This causes the algorithm to consider objects which don't really collide (based on the bounding boxes in the UI) as colliding.

    I plan to play with this a little tonight and start working toward some scripts to assist with object collisions. I don't mind sharing my work once it gets to the point of actually being useful.

    Post edited by djigneo on
  • rbtwhizrbtwhiz Posts: 2,267
    edited December 1969

    The example is intended as a first step toward quickly determining if successive checks are needed. If the world space bounding boxes don't intersect, there is no point in going any further. If they do intersect, you can begin performing more complex calculations that get you a more granular answer.

    -Rob

Sign In or Register to comment.