Picking an object within a box

edited October 2014 in Help request
Having trouble working this out. I found this post and got some tips: https://forum.orx-project.org/discussion/6864#Comment_6868

I want to start without worrying about groups.

This code works for picking via a point:
	orxVECTOR objectPickVector;
	
	objectPickVector.fX = 878;
	objectPickVector.fY = 1185;
	objectPickVector.fZ = -1.0;
	
	orxOBJECT *objectToPick = orxObject_Pick(&objectPickVector, orxU32_UNDEFINED);

This however, doesn't when I try to use an orxOBOX:
	orxOBOX boxArea;
	
	orxVECTOR pivot;
	pivot.fX = 0;
	pivot.fY = 0;
	pivot.fZ = 0;
	
	orxVECTOR position;
	position.fX = 848;
	position.fY = 1130;
	position.fZ = -0.1;	
	
	orxVECTOR size;
	size.fX = 70;
	size.fY = 70;
	size.fZ = 1;	//1 or 0?
	
	orxOBox_2DSet(&boxArea, &position, &pivot, &size, 0);
	
	const orxOBOX area = ballBoxArea;
	
	orxOBJECT *objectToSelect = orxObject_BoxPick(&area, orxNULL);

I just get an orxNULL. Clearly I'm getting a value wrong or using orxOBOX incorrectly. I set size to 1 on the Z axis thinking the greater depth would capture at least one object. Even when I made the size longer, wider and deeper, I only got an orxNULL.

Comments

  • edited October 2014
    This code worked for me:
    if (orxMouse_IsButtonPressed(orxMOUSE_BUTTON_LEFT)){
            orxVECTOR mousePos, worldPos, pivot, size;
            size.fX = size.fY = 40;
            size.fZ = 1.0;
            pivot.fX = pivot.fY = pivot.fZ = 0.;
            if(orxMouse_GetPosition(&mousePos) != orxNULL){
                if(orxRender_GetWorldPosition(&mousePos, orxNULL, &worldPos) != orxNULL){
                    orxOBOX box;
                    orxOBox_2DSet(&box, &worldPos, &pivot, &size, 0);
                    if (orxObject_BoxPick(&box, orxU32_UNDEFINED)){
                        orxLOG("YEY!!");
                    }
                    else{
                        orxLOG("NAAAAY");
                    }
                }
            }
        }
    

    It seems to me that the problem is that you are assuming that the first group id will be 0. I had a similar problem... when I was investigating I found that group ids are kinda random (I think they are a hash index). In my game I use this code to find the actual ids:
    
    // On header file:
    
    enum group_ids_en {
        GROUP_ID_BACKGROUND,
        GROUP_ID_CHAR_SPRITE,
        GROUP_ID_CHAR_HAIR,
        GROUP_ID_CHAR_HELM,
        GROUP_ID_CHAR_ARMOR,
        GROUP_ID_DEFAULT,
        GROUP_ID_MAX
    };
    
    typedef enum group_ids_en groupIds;
    
    struct group_ids_holder_st{
        orxU32 id[GROUP_ID_MAX];
    };
    
    // On the .c file:
    
    void groupIdsInit(orxCAMERA* camera){
    
        orxU32 i;
        for (i = 0; i < GROUP_ID_MAX; i++){
            groupIdsIndex.id[i] = orxCamera_GetGroupID(camera, i);
            orxLOG("Group id %d is %u.", i, groupIdsIndex.id[i]);
        }
    
    }
    

    Here is the output:
    [14:12:20] [LOG] Group id 0 is 3300827270.
    [14:12:20] [LOG] Group id 1 is 1350410992.
    [14:12:20] [LOG] Group id 2 is 4061751890.
    [14:12:20] [LOG] Group id 3 is 2741597886.
    [14:12:20] [LOG] Group id 4 is 1722803689.
    [14:12:20] [LOG] Group id 5 is 1545706559.
  • edited October 2014
    Thanks, Knolan. I just realised from your code. You have orxU32_UNDEFINED and I used orxNULL. So you're right, I'm selecting all groups or none - who knows. But the parameter is wrong.

    If I get no joy, I'll try your routine.
  • edited October 2014
    Hi Knolan, that completely sorted me out. My main problem was accidently not using orxU32_UNDEFINED. But I now need to use groups and get it working cleanly.
  • edited October 2014
    For groups, I ended up going with:

    orxCamera_GetGroupID(camera, 1);

    As I was only concerned with the group on index 1. But I like your system if you have multiple groups to deal with.
  • edited October 2014
    Yeah, I am using the LPC set so I need to use groups to set all the character gear rendered correctly.

    The only problem is that you need to have the enum in the same order as the groups order in the ini file.
  • edited October 2014
    I have a similar setup to Knolan's with the only noticeable difference being that I'm using the config system instead of an enum.

    Here's an example from one of my current projects:

    Config:
    [MainCamera]
    GroupList = Background # Game # Foreground # UI # Overlay # Cursor
    
    [Game]
    PickGroupList = UI # Game # Back
    

    As you can see, I don't want the picking to consider objects from the following groups: Background, Foreground, Overlay and Cursor.
    In addition, I can pick objects from a group called Back which is actually not rendered (in my case, there's a single object covering the whole screen, catching the "lost" clicks as I still want to do some processing on those).

    And here's my picking code:
    orxVECTOR     vMousePos, vPickPos;
    orxU64        u64PickedID = 0;
    ScrollObject *poPickedObject = orxNULL;
    
    // Gets world mouse position
    if(orxRender_GetWorldPosition(orxMouse_GetPosition(&vMousePos), orxNULL, &vMousePos) != orxNULL)
    {
      // Gets picking position
      orxVector_Set(&vPickPos, vMousePos.fX, vMousePos.fY, -orxFLOAT_1);
    
      // For all pickable groups
      orxConfig_PushSection("Game");
      for(orxU32 i = 0, u32Number = orxConfig_GetListCounter("PickGroupList"); i < u32Number; i++)
      {
    #ifdef __TOUCH__
    
        static const orxVECTOR savOffsetList[] =
        {
          {-TOUCH_OFFSET, orxFLOAT_0, orxFLOAT_0},
          {TOUCH_OFFSET, orxFLOAT_0, orxFLOAT_0},
          {orxFLOAT_0, -TOUCH_OFFSET, orxFLOAT_0},
          {orxFLOAT_0, TOUCH_OFFSET, orxFLOAT_0}
        };
    
        // Picks object in it
        poPickedObject = PickObject(vPickPos, savOffsetList, orxARRAY_GET_ITEM_COUNT(savOffsetList), orxString_GetID(orxConfig_GetListString("PickGroupList", i)));
    
    #else // __TOUCH__
    
        // Picks object in it
        poPickedObject = PickObject(vPickPos, orxString_GetID(orxConfig_GetListString("PickGroupList", i)));
    
    #endif // __TOUCH__
    
        // Found?
        if(poPickedObject)
        {
          // Updates picked ID
          u64PickedID = poPickedObject->GetGUID();
    
          // Stops
          break;
        }
      }
      orxConfig_PopSection();
    }
    

    As you can see it's very similar to Knolan's logic. The other difference, which relies on a function I added to Scroll a few days ago, is when __TOUCH__ is defined.
    I do picking at a given position + a list of offsets if nothing's found at the precise position. My offsets are a bit to the left, a bit to the right, a bit above and a bit below.
    That makes life easier for users with big fingers on tiny screens. ;)
Sign In or Register to comment.