Vp object add: Difference between revisions
Jump to navigation
Jump to search
mNo edit summary |
m Added reference number attribute |
||
(5 intermediate revisions by the same user not shown) | |||
Line 2: | Line 2: | ||
|parameters= | |parameters= | ||
|attributes= | |attributes= | ||
{{sdk attribute row|int | | {{sdk attribute row|int |reference_number |Is passed to the callback to identify for which method call it is fired}} | ||
{{sdk attribute row|float | | {{sdk attribute row|int |object_type |Type of object (0 - 3D Model, 2 - Particle emitter, 3 - Path object) }} | ||
{{sdk attribute row|float | | {{sdk attribute row|float |object_x |X coordinate}} | ||
{{sdk attribute row|float | | {{sdk attribute row|float |object_y |Y coordinate}} | ||
{{sdk attribute row|float | | {{sdk attribute row|float |object_z |Z coordinate}} | ||
{{sdk attribute row|float | | {{sdk attribute row|float |object_rotation_x |Rotation X axis}} | ||
{{sdk attribute row|float | | {{sdk attribute row|float |object_rotation_y |Rotation Y axis}} | ||
{{sdk attribute row|float | | {{sdk attribute row|float |object_rotation_z |Rotation Z axis}} | ||
{{sdk attribute row|string | | {{sdk attribute row|float |object_rotation_angle |Rotation angle in radians}} | ||
{{sdk attribute row|string | | {{sdk attribute row|float |object_yaw |Yaw angle in degrees (these are used instead of X,Y,Z axis when rotation angle is set to INFINITY)}} | ||
{{sdk attribute row|string | | {{sdk attribute row|float |object_pitch |Pitch angle in degrees}} | ||
{{sdk attribute row|data | | {{sdk attribute row|float |object_roll |Roll angle in degrees}} | ||
{{sdk attribute row|string |object_model |Model}} | |||
{{sdk attribute row|string |object_action |Action}} | |||
{{sdk attribute row|string |object_description |Description}} | |||
{{sdk attribute row|data |object_data |Data}} | |||
|returncodes= | |returncodes= | ||
{{sdk return code row| | {{sdk return code row|not_in_world|Bot is not currently in a world}} | ||
|returnattributes= | |returnattributes= | ||
{{sdk attribute row|int| | {{sdk attribute row|int|object_id|Object id that was assigned to the new object}} | ||
|behavior= | |behavior= | ||
* Upon successful creation of an object, {{sdk event|OBJECT}} is triggered for those who have subscribed to it. | * Upon successful creation of an object, {{sdk event|OBJECT}} is triggered for those who have subscribed to it. See {{sdk method|event_set}}. | ||
* If {{sdk attribute|object_rotation_angle}} is set to INFINITY then it will be stored as that in world. The euler angles will be not be converted to an equivalent axis-angle representation. See examples for euler to axis-angle conversion code. | |||
|caveats= | |caveats= | ||
|examples= | |examples= | ||
Build a street1.rwx object at 0X 0Y 0Z. | |||
<syntaxhighlight lang="c"> | |||
void handle_object_add(VPInstance sdk, int rc, int ref) | |||
{ | |||
if (rc) | |||
printf("Couldn't build object (reason %d)\n", rc); | |||
else | |||
printf("Object built successfully!\n"); | |||
} | |||
int main(int argc, const char* argv[]) | |||
{ | |||
//... | |||
vp_callback_set(sdk, VP_CALLBACK_OBJECT_ADD, handle_object_add); | |||
vp_int_set(sdk, VP_OBJECT_TYPE, 0); // 3D Model | |||
vp_float_set(sdk, VP_OBJECT_X, 0.0); | |||
vp_float_set(sdk, VP_OBJECT_Y, 0.0); | |||
vp_float_set(sdk, VP_OBJECT_Z, 0.0); | |||
vp_float_set(sdk, VP_OBJECT_ROTATION_X, 0.0); | |||
vp_float_set(sdk, VP_OBJECT_ROTATION_Y, 0.0); | |||
vp_float_set(sdk, VP_OBJECT_ROTATION_Z, 0.0); | |||
vp_float_set(sdk, VP_OBJECT_ROTATION_ANGLE, 0.0); | |||
vp_string_set(sdk, VP_OBJECT_MODEL, "street1.rwx"); | |||
vp_string_set(sdk, VP_OBJECT_ACTION, ""); | |||
vp_string_set(sdk, VP_OBJECT_DESCRIPTION, ""); | |||
rc = vp_object_add(sdk); | |||
if (rc) | |||
printf("Couldn't build object (reason %d)\n", rc); | |||
//... | |||
} | |||
</syntaxhighlight> | |||
Convert euler angles (in degrees) to axis-angle. | |||
<syntaxhighlight lang="c"> | |||
void euler_to_axis_angle(double yaw, double pitch, double roll, double *x, double *y, double *z, double *angle) | |||
{ | |||
// Convert angles to radians | |||
yaw = (yaw / 180.0) * M_PI; | |||
pitch = (pitch / 180.0) * M_PI; | |||
roll = (roll / 180.0) * M_PI; | |||
// Convert to axis-angle | |||
double sin_yaw_2, sin_pitch_2, sin_roll_2, cos_yaw_2, cos_pitch_2, cos_roll_2; | |||
sin_yaw_2 = sin(yaw / 2); | |||
sin_pitch_2 = sin(pitch / 2); | |||
sin_roll_2 = sin(roll / 2); | |||
cos_yaw_2 = cos(yaw / 2); | |||
cos_pitch_2 = cos(pitch / 2); | |||
cos_roll_2 = cos(roll / 2); | |||
// Return a normalized axis | |||
double x_tmp, y_tmp, z_tmp; | |||
x_tmp = sin_yaw_2 * sin_roll_2 * cos_pitch_2 + cos_yaw_2 * cos_roll_2 * sin_pitch_2; | |||
y_tmp = sin_yaw_2 * cos_roll_2 * cos_pitch_2 + cos_yaw_2 * sin_roll_2 * sin_pitch_2; | |||
z_tmp = cos_yaw_2 * sin_roll_2 * cos_pitch_2 - sin_yaw_2 * cos_roll_2 * sin_pitch_2; | |||
double norm = sqrt(x_tmp * x_tmp + y_tmp * y_tmp + z_tmp * z_tmp); | |||
if (norm) | |||
{ | |||
*x = x_tmp / norm; | |||
*y = y_tmp / norm; | |||
*z = z_tmp / norm; | |||
} | |||
else | |||
{ | |||
*x = 1; | |||
*y = 0; | |||
*z = 0; | |||
} | |||
*angle = 2 * acos(cos_yaw_2 * cos_pitch_2 * cos_roll_2 - sin_yaw_2 * sin_pitch_2 * sin_roll_2); | |||
} | |||
</syntaxhighlight> | |||
Convert axis-angle to euler angles (in degrees). | |||
<syntaxhighlight lang="c"> | |||
void axis_angle_to_euler(double x, double y, double z, double angle, double *yaw, double *pitch, double *roll) | |||
{ | |||
// Normalize axis | |||
double norm = sqrt(x * x + y * y + z * z); | |||
if (norm) | |||
{ | |||
x = x / norm; | |||
y = y / norm; | |||
z = z / norm; | |||
} | |||
else | |||
{ | |||
*yaw = 0; | |||
*pitch = 0; | |||
*roll = 0; | |||
return; | |||
} | |||
double sin_angle, cos_angle, cos_angle_1; | |||
sin_angle = sin(angle); | |||
cos_angle = cos(angle); | |||
cos_angle_1 = 1 - cos(angle); | |||
double yaw_tmp, pitch_tmp, roll_tmp; | |||
if ((x * y * cos_angle_1 + z * sin_angle) > 0.998) // North pole singularity detected | |||
{ | |||
yaw_tmp = 2 * atan2(x * sin(angle / 2), cos(angle / 2)); | |||
pitch_tmp = 0; | |||
roll_tmp = M_PI_2; | |||
} | |||
else if ((x * y * cos_angle_1 + z * sin_angle) < -0.998) // South pole singularity detected | |||
{ | |||
yaw_tmp = -2 * atan2(x * sin(angle / 2), cos(angle / 2)); | |||
pitch_tmp = 0; | |||
roll_tmp = -M_PI_2; | |||
} | |||
else | |||
{ | |||
yaw_tmp = atan2(y * sin_angle - x * z * cos_angle_1, 1 - (y * y + z * z) * cos_angle_1); | |||
pitch_tmp = atan2(x * sin_angle - y * z * cos_angle_1, 1 - (x * x + z * z) * cos_angle_1); | |||
roll_tmp = asin(x * y * cos_angle_1 + z * sin_angle); | |||
} | |||
*yaw = (yaw_tmp * 180) / M_PI; | |||
*pitch = (pitch_tmp * 180) / M_PI; | |||
*roll = (roll_tmp * 180) / M_PI; | |||
} | |||
</syntaxhighlight> | |||
|seealso= | |seealso= | ||
* {{sdk method|object_change}} | * {{sdk method|object_change}} | ||
* {{sdk method|object_delete}} | * {{sdk method|object_delete}} | ||
* {{sdk callback| | * {{sdk callback|object_add}} | ||
}} | }} |
Latest revision as of 23:14, 31 July 2018
Method call snippet
vp_object_add(instance);
Build a new object.
Parameters
These are the parameters that this method requires:
Parameter | Usage |
---|---|
VPInstance instance |
Pointer to the instance this method call is intended for |
Used attributes
This method uses data set in these attributes when called:
Attribute | Usage | |
---|---|---|
VP_REFERENCE_NUMBER | Is passed to the callback to identify for which method call it is fired | |
VP_OBJECT_TYPE | Type of object (0 - 3D Model, 2 - Particle emitter, 3 - Path object) | |
VP_OBJECT_X | X coordinate | |
VP_OBJECT_Y | Y coordinate | |
VP_OBJECT_Z | Z coordinate | |
VP_OBJECT_ROTATION_X | Rotation X axis | |
VP_OBJECT_ROTATION_Y | Rotation Y axis | |
VP_OBJECT_ROTATION_Z | Rotation Z axis | |
VP_OBJECT_ROTATION_ANGLE | Rotation angle in radians | |
VP_OBJECT_YAW | Yaw angle in degrees (these are used instead of X,Y,Z axis when rotation angle is set to INFINITY) | |
VP_OBJECT_PITCH | Pitch angle in degrees | |
VP_OBJECT_ROLL | Roll angle in degrees | |
VP_OBJECT_MODEL | Model | |
VP_OBJECT_ACTION | Action | |
VP_OBJECT_DESCRIPTION | Description | |
VP_OBJECT_DATA | Data |
Returns
This method returns a return code integer, which indicates whether the call was successful or errored for any reason:
Return code | Cause |
---|---|
VP_RC_SUCCESS |
Successful call (for methods that have a registered callback, it only means the request has been sent) |
VP_RC_NOT_IN_WORLD |
Bot is not currently in a world |
The following attributes will be returned in VP_CALLBACK_OBJECT_ADD
if the operation was successful:
Attribute | Usage | Also returned for |
---|---|---|
VP_OBJECT_ID | Object id that was assigned to the new object |
Behavior
- Upon successful creation of an object,
VP_EVENT_OBJECT
is triggered for those who have subscribed to it. Seevp_event_set()
. - If
VP_OBJECT_ROTATION_ANGLE
is set to INFINITY then it will be stored as that in world. The euler angles will be not be converted to an equivalent axis-angle representation. See examples for euler to axis-angle conversion code.
Examples
Build a street1.rwx object at 0X 0Y 0Z.
void handle_object_add(VPInstance sdk, int rc, int ref)
{
if (rc)
printf("Couldn't build object (reason %d)\n", rc);
else
printf("Object built successfully!\n");
}
int main(int argc, const char* argv[])
{
//...
vp_callback_set(sdk, VP_CALLBACK_OBJECT_ADD, handle_object_add);
vp_int_set(sdk, VP_OBJECT_TYPE, 0); // 3D Model
vp_float_set(sdk, VP_OBJECT_X, 0.0);
vp_float_set(sdk, VP_OBJECT_Y, 0.0);
vp_float_set(sdk, VP_OBJECT_Z, 0.0);
vp_float_set(sdk, VP_OBJECT_ROTATION_X, 0.0);
vp_float_set(sdk, VP_OBJECT_ROTATION_Y, 0.0);
vp_float_set(sdk, VP_OBJECT_ROTATION_Z, 0.0);
vp_float_set(sdk, VP_OBJECT_ROTATION_ANGLE, 0.0);
vp_string_set(sdk, VP_OBJECT_MODEL, "street1.rwx");
vp_string_set(sdk, VP_OBJECT_ACTION, "");
vp_string_set(sdk, VP_OBJECT_DESCRIPTION, "");
rc = vp_object_add(sdk);
if (rc)
printf("Couldn't build object (reason %d)\n", rc);
//...
}
Convert euler angles (in degrees) to axis-angle.
void euler_to_axis_angle(double yaw, double pitch, double roll, double *x, double *y, double *z, double *angle)
{
// Convert angles to radians
yaw = (yaw / 180.0) * M_PI;
pitch = (pitch / 180.0) * M_PI;
roll = (roll / 180.0) * M_PI;
// Convert to axis-angle
double sin_yaw_2, sin_pitch_2, sin_roll_2, cos_yaw_2, cos_pitch_2, cos_roll_2;
sin_yaw_2 = sin(yaw / 2);
sin_pitch_2 = sin(pitch / 2);
sin_roll_2 = sin(roll / 2);
cos_yaw_2 = cos(yaw / 2);
cos_pitch_2 = cos(pitch / 2);
cos_roll_2 = cos(roll / 2);
// Return a normalized axis
double x_tmp, y_tmp, z_tmp;
x_tmp = sin_yaw_2 * sin_roll_2 * cos_pitch_2 + cos_yaw_2 * cos_roll_2 * sin_pitch_2;
y_tmp = sin_yaw_2 * cos_roll_2 * cos_pitch_2 + cos_yaw_2 * sin_roll_2 * sin_pitch_2;
z_tmp = cos_yaw_2 * sin_roll_2 * cos_pitch_2 - sin_yaw_2 * cos_roll_2 * sin_pitch_2;
double norm = sqrt(x_tmp * x_tmp + y_tmp * y_tmp + z_tmp * z_tmp);
if (norm)
{
*x = x_tmp / norm;
*y = y_tmp / norm;
*z = z_tmp / norm;
}
else
{
*x = 1;
*y = 0;
*z = 0;
}
*angle = 2 * acos(cos_yaw_2 * cos_pitch_2 * cos_roll_2 - sin_yaw_2 * sin_pitch_2 * sin_roll_2);
}
Convert axis-angle to euler angles (in degrees).
void axis_angle_to_euler(double x, double y, double z, double angle, double *yaw, double *pitch, double *roll)
{
// Normalize axis
double norm = sqrt(x * x + y * y + z * z);
if (norm)
{
x = x / norm;
y = y / norm;
z = z / norm;
}
else
{
*yaw = 0;
*pitch = 0;
*roll = 0;
return;
}
double sin_angle, cos_angle, cos_angle_1;
sin_angle = sin(angle);
cos_angle = cos(angle);
cos_angle_1 = 1 - cos(angle);
double yaw_tmp, pitch_tmp, roll_tmp;
if ((x * y * cos_angle_1 + z * sin_angle) > 0.998) // North pole singularity detected
{
yaw_tmp = 2 * atan2(x * sin(angle / 2), cos(angle / 2));
pitch_tmp = 0;
roll_tmp = M_PI_2;
}
else if ((x * y * cos_angle_1 + z * sin_angle) < -0.998) // South pole singularity detected
{
yaw_tmp = -2 * atan2(x * sin(angle / 2), cos(angle / 2));
pitch_tmp = 0;
roll_tmp = -M_PI_2;
}
else
{
yaw_tmp = atan2(y * sin_angle - x * z * cos_angle_1, 1 - (y * y + z * z) * cos_angle_1);
pitch_tmp = atan2(x * sin_angle - y * z * cos_angle_1, 1 - (x * x + z * z) * cos_angle_1);
roll_tmp = asin(x * y * cos_angle_1 + z * sin_angle);
}
*yaw = (yaw_tmp * 180) / M_PI;
*pitch = (pitch_tmp * 180) / M_PI;
*roll = (roll_tmp * 180) / M_PI;
}