26.12.2013, 13:19
First function gets the slope of a given x, y coordinate (this won't work under bridges and some other places) it will return the RX, RY angles of the slope
The second function will let you rotate objects on a slope that have been placed with GetSlope() you supply the RX, RY, RZ rotation and the amount of z rotation (spin) it will return correct RX, RY, RZ orientation.
(Thanks to Stylock for the ObjectRotateZ() function)
So there you go don't you wish you paid more attention to trig in school ?
The second function will let you rotate objects on a slope that have been placed with GetSlope() you supply the RX, RY, RZ rotation and the amount of z rotation (spin) it will return correct RX, RY, RZ orientation.
(Thanks to Stylock for the ObjectRotateZ() function)
So there you go don't you wish you paid more attention to trig in school ?
pawn Код:
stock GetSlope(x, y, &RXAngle, &RYAngle)
{
new Float:North[3], Float:South[3], Float:East[3], Float:West[3], Float:opposite, Float:hypotenuse;
// Set slope positions
North[0] = x;
North[1] = y + 1;
South[0] = x;
South[1] = y - 1;
East[0] = x + 1;
East[1] = y;
West[0] = x - 1;
West[1] = y;
// Use map andreas to get Z Values
MapAndreas_FindZ_For2DCoord(North[0], North[1], North[2]);
MapAndreas_FindZ_For2DCoord(South[0], South[1], South[2]);
MapAndreas_FindZ_For2DCoord(East[0], East[1], East[2]);
MapAndreas_FindZ_For2DCoord(West[0], West[1], West[2]);
// Calculate Slope angles
// North South RX
hypotenuse = getdist3d(North[0], North[1], North[2], South[0], South[1], South[2]);
opposite = getdist3d(North[0], North[1], North[2], North[0], North[1], South[2]);
RXAngle = asin(floatdiv(opposite, hypotenuse));
if(South[2] > North[2]) RXAngle *= -1;
// West East RY
hypotenuse = getdist3d(West[0], West[1], West[2], East[0], East[1], East[2]);
opposite = getdist3d(West[0], West[1], West[2], West[0], West[1], East[2]);
RYAngle = asin(floatdiv(opposite, hypotenuse));
if(East[2] > West[2]) RYAngle *= -1;
return 1;
}
stock ObjectRotateZ(Float:RX, Float:RY, Float:RZ, Float:rot_z, &Float:NewRX, &Float:NewRY, &Float:NewRZ)
{
new
Float:sinx,
Float:siny,
Float:sinz,
Float:cosx,
Float:cosy,
Float:cosz;
FloatConvertValue(RX, RY, RZ, sinx, siny, sinz, cosx, cosy, cosz);
// Convert from one euler angle sequence (ZXY) to another and add the rotation
FloatConvertValue(asin(cosx * cosy), atan2(sinx, cosx * siny) + rot_z, atan2(cosy * cosz * sinx - siny * sinz, cosz * siny - cosy * sinx * -sinz),
sinx, siny, sinz, cosx, cosy, cosz);
// Convert back to the original euler angle sequence and apply the new rotation to the object
NewRX = asin(cosx * siny),
NewRY = atan2(cosx * cosy, sinx),
NewRZ = atan2(cosz * sinx * siny - cosy * sinz, cosy * cosz + sinx * siny * sinz);
return 1;
}
stock FloatConvertValue(Float:rot_x, Float:rot_y, Float:rot_z, &Float:sinx, &Float:siny, &Float:sinz, &Float:cosx, &Float:cosy, &Float:cosz)
{
sinx = floatsin(rot_x, degrees);
siny = floatsin(rot_y, degrees);
sinz = floatsin(rot_z, degrees);
cosx = floatcos(rot_x, degrees);
cosy = floatcos(rot_y, degrees);
cosz = floatcos(rot_z, degrees);
return 1;
}

