Vp object add: Difference between revisions

From Virtual Paradise Wiki
Jump to navigation Jump to search
Sleepy E (talk | contribs)
Added euler to angle-axis conversion code
Sleepy E (talk | contribs)
m Added reference number attribute
 
(2 intermediate revisions by the same user not shown)
Line 2: Line 2:
|parameters=
|parameters=
|attributes=
|attributes=
  {{sdk attribute row|int    |reference_number      |Is passed to the callback to identify for which method call it is fired}}
   {{sdk attribute row|int    |object_type          |Type of object (0 - 3D Model, 2 - Particle emitter, 3 - Path object) }}
   {{sdk attribute row|int    |object_type          |Type of object (0 - 3D Model, 2 - Particle emitter, 3 - Path object) }}
   {{sdk attribute row|float  |object_x              |X coordinate}}
   {{sdk attribute row|float  |object_x              |X coordinate}}
Line 22: Line 23:
   {{sdk attribute row|int|object_id|Object id that was assigned to the new object}}
   {{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.
* 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=
Line 62: Line 63:
</syntaxhighlight>
</syntaxhighlight>


Convert euler angles (in degrees) to axis-angle representation.
Convert euler angles (in degrees) to axis-angle.
<syntaxhighlight lang="c">
<syntaxhighlight lang="c">
void rotate(double yaw, double pitch, double roll, double *x, double *y, double *z, double *angle)
void euler_to_axis_angle(double yaw, double pitch, double roll, double *x, double *y, double *z, double *angle)
{
{
   // Convert angles to radians
   // Convert angles to radians
Line 107: Line 108:


   *angle = 2 * acos(cos_yaw_2 * cos_pitch_2 * cos_roll_2 - sin_yaw_2 * sin_pitch_2 * sin_roll_2);
   *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>
</syntaxhighlight>

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

See also