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.
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;
}