Rotating offsets from center of object
#1

I'm currently working on a game that involves materials to be combined on a working table in order to produce drugs/chemicals. Then the player would have to place a chem-kit on it with some /placesomething command.

I've placed a table object (937) with 0.0 Z-rotation, then I've placed some objects on it for simulating some containers for the products. Then I've taken all offsets from those objects by subtracting the coordinates of the table.

Example result:


Obivously, those offsets are valid only if the table has a Z-rotation of 0.0 and they would fail if the table has a different rotation.
So, I've been working on this snippet of code based on GetXYInDirection function for hours, but I still haven't figured out how to rotate those offsets accordingly on the table rotation.

My not working code (bad result: http://*******/HZBLDD)
pawn Код:
const Float:tablerot = ... ,
      Float:tablex = ... ,
      Float:tabley = ... ,
      Float:tablez = ... ;

stock const tableItems[] =
{
    ...
};

stock const Float:tableItemsOffsets[sizeof(tableItems)][6] =
{
    ...
};

new Float:sin = floatsin(tablerot+180.0, degrees),
    Float:cos = floatcos(tablerot+180.0, degrees);

CreateDynamicObject(937, tablex, tabley, tablez, 0.000000, 0.000000, tablerot);

new Float:X, Float:Y;

for(new i; i < sizeof(tableItems); i++)
{
    //X = tablex - tableItemsOffsets[i][0];
    //Y = tabley - tableItemsOffsets[i][1];

    X = tablex + (tableItemsOffsets[i][0] * sin);
    Y = tabley + (tableItemsOffsets[i][1] * cos);

    CreateDynamicObject(tableItems[i],
                        X,
                        Y,
                        tablez + tableItemsOffsets[i][2],
                        tableItemsOffsets[i][3],
                        tableItemsOffsets[i][4],
                        tablerot-tableItemsOffsets[i][5]);
}
Thanks in advance for any help since this is really driving me mad!
Reply
#2

You could just use AttachObjectToObject(you are using a streamer so its probably AttachDynamicObjectToObject or something) to attach the container objects and such to the table itself, that way it will have the correct offsets no matter what rotation the table has. However, if the containers need to be moved around while the crafting is going on, this is probably not the best option.
Reply
#3

I just need to place the objects on the table before the crafting starts.
Unfortunately, there's no AttachDynamicObjectToObject available.
Reply
#4

It's not that hard to do with the right functions just take a look at map mover.

https://sampforum.blast.hk/showthread.php?tid=506610

pawn Код:
AttachObjectToObjectEx(attachoid, Float:off_x, Float:off_y, Float:off_z, Float:rot_x, Float:rot_y, Float:rot_z, &Float:X, &Float:Y, &Float:Z, &Float:RX, &Float:RY, &Float:RZ, pobject = -1) // By Stylock - http://forum.sa-mp.com/member.php?u=114165
{
        static
                Float:sin[3],
                Float:cos[3],
                Float:pos[3],
                Float:rot[3];
        if(pobject == -1)
        {
                GetObjectPos(attachoid, pos[0], pos[1], pos[2]);
                GetObjectRot(attachoid, rot[0], rot[1], rot[2]);
        }
        else
        {
                GetPlayerObjectPos(pobject, attachoid, pos[0], pos[1], pos[2]);
                GetPlayerObjectRot(pobject, attachoid, rot[0], rot[1], rot[2]);
        }
        EDIT_FloatEulerFix(rot[0], rot[1], rot[2]);
        cos[0] = floatcos(rot[0], degrees); cos[1] = floatcos(rot[1], degrees); cos[2] = floatcos(rot[2], degrees); sin[0] = floatsin(rot[0], degrees); sin[1] = floatsin(rot[1], degrees); sin[2] = floatsin(rot[2], degrees);
        pos[0] = pos[0] + off_x * cos[1] * cos[2] - off_x * sin[0] * sin[1] * sin[2] - off_y * cos[0] * sin[2] + off_z * sin[1] * cos[2] + off_z * sin[0] * cos[1] * sin[2];
        pos[1] = pos[1] + off_x * cos[1] * sin[2] + off_x * sin[0] * sin[1] * cos[2] + off_y * cos[0] * cos[2] + off_z * sin[1] * sin[2] - off_z * sin[0] * cos[1] * cos[2];
        pos[2] = pos[2] - off_x * cos[0] * sin[1] + off_y * sin[0] + off_z * cos[0] * cos[1];
        rot[0] = asin(cos[0] * cos[1]); rot[1] = atan2(sin[0], cos[0] * sin[1]) + rot_z; rot[2] = atan2(cos[1] * cos[2] * sin[0] - sin[1] * sin[2], cos[2] * sin[1] - cos[1] * sin[0] * -sin[2]);
        cos[0] = floatcos(rot[0], degrees); cos[1] = floatcos(rot[1], degrees); cos[2] = floatcos(rot[2], degrees); sin[0] = floatsin(rot[0], degrees); sin[1] = floatsin(rot[1], degrees); sin[2] = floatsin(rot[2], degrees);
        rot[0] = asin(cos[0] * sin[1]); rot[1] = atan2(cos[0] * cos[1], sin[0]); rot[2] = atan2(cos[2] * sin[0] * sin[1] - cos[1] * sin[2], cos[1] * cos[2] + sin[0] * sin[1] * sin[2]);
        cos[0] = floatcos(rot[0], degrees); cos[1] = floatcos(rot[1], degrees); cos[2] = floatcos(rot[2], degrees); sin[0] = floatsin(rot[0], degrees); sin[1] = floatsin(rot[1], degrees); sin[2] = floatsin(rot[2], degrees);
        rot[0] = atan2(sin[0], cos[0] * cos[1]) + rot_x; rot[1] = asin(cos[0] * sin[1]); rot[2] = atan2(cos[2] * sin[0] * sin[1] + cos[1] * sin[2], cos[1] * cos[2] - sin[0] * sin[1] * sin[2]);
        cos[0] = floatcos(rot[0], degrees); cos[1] = floatcos(rot[1], degrees); cos[2] = floatcos(rot[2], degrees); sin[0] = floatsin(rot[0], degrees); sin[1] = floatsin(rot[1], degrees); sin[2] = floatsin(rot[2], degrees);
        rot[0] = asin(cos[1] * sin[0]); rot[1] = atan2(sin[1], cos[0] * cos[1]) + rot_y; rot[2] = atan2(cos[0] * sin[2] - cos[2] * sin[0] * sin[1], cos[0] * cos[2] + sin[0] * sin[1] * sin[2]);
        X = pos[0];
        Y = pos[1];
        Z = pos[2];
        RX = rot[0];
        RY = rot[1];
        RZ = rot[2];
}
 
 
EDIT_FloatEulerFix(&Float:rot_x, &Float:rot_y, &Float:rot_z)
{
    EDIT_FloatGetRemainder(rot_x, rot_y, rot_z);
    if((!floatcmp(rot_x, 0.0) || !floatcmp(rot_x, 360.0))
    && (!floatcmp(rot_y, 0.0) || !floatcmp(rot_y, 360.0)))
    {
        rot_y = 0.0000002;
    }
    return 1;
}
 
EDIT_FloatGetRemainder(&Float:rot_x, &Float:rot_y, &Float:rot_z)
{
    EDIT_FloatRemainder(rot_x, 360.0);
    EDIT_FloatRemainder(rot_y, 360.0);
    EDIT_FloatRemainder(rot_z, 360.0);
    return 1;
}
 
EDIT_FloatRemainder(&Float:remainder, Float:value)
{
    if(remainder >= value)
    {
        while(remainder >= value)
        {
            remainder = remainder - value;
        }
    }
    else if(remainder < 0.0)
    {
        while(remainder < 0.0)
        {
            remainder = remainder + value;
        }
    }
    return 1;
}
So basically do this.

1.) Place table at angle
2.) Translate saved offsets and rotations for each object
3.) Set the new position of each object

Let me just explain so there is no confusion.

pawn Код:
AttachObjectToObjectEx(attachoid, Float:off_x, Float:off_y, Float:off_z, Float:rot_x, Float:rot_y, Float:rot_z, &Float:X, &Float:Y, &Float:Z, &Float:RX, &Float:RY, &Float:RZ, pobject = -1) // By Stylock - http://forum.sa-mp.com/member.php?u=114165
//attachoid - Table object
//Float:off_x..Float:rot_z - Position and rotation of object on table when table has a position&rotation of 0.0, 0.0, 0.0
//&Float:X..&Float:RZ - This function will return the new coordinates for use
Reply
#5

Awesome, it's working!


Thank you so much, I've been wasting so much time on this.
P.S. Apparently I've already gave you some reputation some time ago, so I can't give you more at this time.
Reply
#6

No problem, pretty easy once you have the correct functions isn't it ?
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)