attachChild: Difference between revisions

From Bohemia Interactive Community
(Created page with "{{RV|type=command |game1= arma3 |version1= 2.22 |branch= dev |arg=local |eff=global |serverExec= |gr1= Object Manipulation |descr={{Wiki|WIP}} Attaches a child object to a parent, similar to attachTo but instead of a rigid/forced attachment its using a PhysX joint. {{Feature|informative|For more information see {{Link|https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/Joints.html|NVIDIA docs}}.}} {{Feature|informative|Does NOT beh...")
 
m (Formatting)
Line 28: Line 28:


|p3= jointType: [[String]] - Currently only "6DOFJoint" and "RevoluteJoint" and "FixedJoint"<br>
|p3= jointType: [[String]] - Currently only "6DOFJoint" and "RevoluteJoint" and "FixedJoint"<br>
A 6DOFJoint allows to configure all axis (XYZ translation, Pitch/Yaw/Roll rotation) limits and drives.<br>
 
A RevoluteJoint only allows rotation around the X axis, a Revolute joint can also be implemented with a 6DOFJoint and the appropriate limits (internally it is implemented exactly like that)<br>
<div class="_description">
A FixedJoint is limited in all axis, it essentially works like a PhysX based attachTo.<br>
; 6DOFJoint
: Allows to configure all axis (XYZ translation, Pitch/Yaw/Roll rotation) limits and drives.
; RevoluteJoint
: Only allows rotation around the X axis, a Revolute joint can also be implemented with a 6DOFJoint and the appropriate limits (internally it is implemented exactly like that)
; FixedJoint
: Limited in all axis, it essentially works like a PhysX based attachTo.
</div>


|p4= localFrameParent: [[Array]] - The Position and orientation, in parent's model-space of where the joint will be placed.<br>
|p4= localFrameParent: [[Array]] - The Position and orientation, in parent's model-space of where the joint will be placed.<br>
Line 49: Line 55:
|p5= localFrameChild: [[Array]] - The Position and orientation, in child's model-space of where the joint will be placed.
|p5= localFrameChild: [[Array]] - The Position and orientation, in child's model-space of where the joint will be placed.


|p6= miscFlags: [[Array]] - [collisionEnabled (Default [[false]]), breakForce (Default -1)]
|p6= miscFlags: [[Array]] - [(collisionEnabled, breakForce)]
 
<div class="_description">
;
: collisionEnabled: [[Boolean]] (Optional, Default: [[false]]) - When false, disables collision between the two joint-ed objects
;
: breakForce: [[Number]] (Optional, Default: -1)
;
: limitsAreForces?
</div>




|p7= jointDescription: [[Array]] - This specifies the behavior/limits of the joint.<br>
|p7= jointDescription: [[Array]] - This specifies the behavior/limits of the joint.<br>
[(linearLimit, swingLimit, twistLimit, drives)] <br>
[(linearLimit, swingLimit, twistLimit, drives)] <br><br>Note that all are optional. Passing an empty array is equivalent to using a "FixedJoint" type<br><br><div class="_description">
<br>
; linearLimit
Note that all are optional. Passing an empty array is equivalent to using a "FixedJoint" type<br>
: [[Array]] - Linear limit specifies the joints permitted translation along the XYZ axis.<br>There are three types of linear limits, fully locked, per-axis limit and distance limit.<br><br><div class="_description">
<br>
:; Fully Locked<nowiki>:</nowiki>
linearLimit: [[Array]] - <br>
:: []<br>Empty array, will completely lock the XYZ translational axes, only allowing rotational movement (If allowed in the swing/twist limits)
<br>
:; Per axis<nowiki>:</nowiki>
Linear limit specifies the joints permitted translation along the XYZ axis.<br>
:: [limitX, limitY, limitZ]<br><div class="_description">
There are three types of linear limits, fully locked, per-axis limit and distance limit.<br>
::; limit*<nowiki>:</nowiki>
<br>
::: [[Array]] - [lowerLimit, upperLimit, springParameters] <div class="_description">
Fully Locked:<br>
:::; lowerLimit<nowiki>:</nowiki>
[]<br>
:::: [[Number]] - The minimum permitted offset on the axis
Empty array, will completely lock the XYZ translational axes, only allowing rotational movement (If allowed in the swing/twist limits)<br>
:::; upperLimit<nowiki>:</nowiki>
<br>
:::: [[Number]] - The maximum permitted offset on the axis<br> upperLimit must be larger than lowerLimit
Per axis:<br>
:::; springParameters<nowiki>:</nowiki>
[limitX, limitY, limitZ]<br>
:::: [[Array]] - [(restitution, spring, damping)]<br>All spring parameters are optional, but for the linear limits, atleast an empty array must be provided. <div class="_description">
limit*: [[Array]] - [lowerLimit, upperLimit, springParameters]<br>
::::; restitiution<nowiki>:</nowiki>
lowerLimit: [[Number]] - The minimum permitted offset on the axis<br>
::::: [[Number]] (Optional, Default: 0) - Must be between 0-1.<br> Controls the amount of bounce when the joint hits a limit.<br> A restitution value of 1.0 causes the joint to bounce back with the velocity which it hit the limit.<br> A value of zero causes the joint to stop dead.<br> {{Link|https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/apireference/files/classPxJointLimitParameters.html#cf208a0f1e54fb8e9219af1e0357d4a9|NVIDIA docs}}
upperLimit: [[Number]] - The maximum permitted offset on the axis<br>
::::; spring<nowiki>:</nowiki>
upperLimit must be larger than lowerLimit<br>
::::: [[Number]] (Optional, Default: 0) - Must be 0 or greater.<br> if greater than zero, the limit is soft, i.e. a spring pulls the joint back to the limit  
springParameters: [[Array]] - [(restitution, spring, damping)]<br>
::::; damping<nowiki>:</nowiki>
restitiution: [[Number]] (Optional, Default: 0) - Must be between 0-1.<br>
::::: [[Number]] (Optional, Default: 0) - Must be 0 or greater. if spring is greater than zero, this is the damping of the limit spring</div>
Controls the amount of bounce when the joint hits a limit.<br>
::; Distance Limit
A restitution value of 1.0 causes the joint to bounce back with the velocity which it hit the limit.<br>
::: [xLocked, yLocked, zLocked, distanceLimit, springParameters]<br> <div class="_description">
A value of zero causes the joint to stop dead.<br>
:::; <nowiki>*</nowiki>Locked<nowiki>:</nowiki>
{{Link|https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/apireference/files/classPxJointLimitParameters.html#cf208a0f1e54fb8e9219af1e0357d4a9|NVIDIA docs}}<br>
:::: [[Boolean]] - Whether the axis is completely locked and no translation is allowed along it
spring: [[Number]] (Optional, Default: 0) - Must be 0 or greater.<br>
:::; distanceLimit<nowiki>:</nowiki>
if greater than zero, the limit is soft, i.e. a spring pulls the joint back to the limit <br>
:::: [[Number]] - Distance on meters, as a radius/sphere around the joint.
damping: [[Number]] (Optional, Default: 0) - Must be 0 or greater. if spring is greater than zero, this is the damping of the limit spring <br>
:; swingLimit<nowiki>:</nowiki>
<br>
:: [[Array]] - [(swingX, swingZ, springParameters)]<br>All parameters are optional, the default is both swing axis being locked<br>Swing limit comes in two types, cone and pyramid. Which variant is used depends on the datatype inside the swing parameter<br>Note that cone cannot be combined with pyramid, either both are cone or both are pyramid.<br>If the swing limit is [[pi]], the rotation around that axis is fully unlocked/free.<div class="_description">
All spring parameters are optional, but for the distance limits, atleast an empty array must be provided.<br>
::; Cone limit<nowiki>:</nowiki>
<br>
::: swingX<nowiki>:</nowiki> [[Number]] (Optional, Default 0/locked) - The rotation around the X (right) axis, thus the pitch. Rotation in radians, between [[pi]] and [[pi]].
Distance Limit:<br>
::;
[xLocked, yLocked, zLocked, distanceLimit(, springParameters)]<br>
::: swingZ<nowiki>:</nowiki> [[Number]] (Optional, Default 0/locked) - The rotation around the Z (up) axis, thus the yaw. Rotation in radians, between [[pi]] and [[pi]].
*Locked: [[Boolean]] - Whether the axis is completely locked and no translation is allowed along it<br>
::; Pyramid limit<nowiki>:</nowiki>
distanceLimit: [[Number]] - Distance on meters, as a radius/sphere around the joint.<br>
::: swingX<nowiki>:</nowiki> [[Array]] - [(min, max)] - Same rotation in radians as the cone limit, but it can be asymmetrical.
<br>
::;
<br>
::: swingZ<nowiki>:</nowiki> [[Array]] - [(min, max)] - Same rotation in radians as the cone limit, but it can be asymmetrical.
swingLimit: [[Array]] - [(swingX, swingZ, springParameters)]<br>
:; twistLimit<nowiki>:</nowiki>
All parameters are optional, the default is both swing axis being locked<br>
:: [[Array]] - [(twistLower, twistUpper, springParameters)]<br>Twist is rotation about the Y (front/dir) axis, thus the roll.<br>Left and right twist limits can be configured independently.<br><div class="_description">
Swing limit comes in two types, cone and pyramid. Which variant is used depends on the datatype inside the swing parameter<br>
::; twist<nowiki>*:</nowiki>
swingX is the rotation around the X (right) axis, thus the pitch.<br>
::: [[Number]] (Optional, Default: 0) - Rotation limit in radians, between -2[[pi]] and 2[[pi]]<br> 0 means twist is locked, and 2*pi means its completely unlocked<br>
swingZ is the rotation around the Z (up) axis, thus the yaw.<br>
:; drives<nowiki>:</nowiki>
<br>
:: [[Array]] - [(angularTwistDrive, angularSwingDrive, angularSlerpDrive, linearXDrive, linearYDrive, linearZDrive, limitsAreForces)]<br>Drives allow to apply force into the joint on any of the axes.<br>Each drive is a spring, one end being on the joint, and the other end being on the target specified by the commands:<br>[[setJointDrivePosition]] [[setJointDriveOrientation]] [[setJointDriveLinearVelocity]] [[setJointDriveAngularVelocity]]<br>For rotational drives there are two variants, Swing+Twist or SLERP (Spherical Linear Interpolation)<br>See {{Link|https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/Joints.html#drives|NVIDIA docs}}<div class="_description">
Cone limit:<br>
::; *Drive<nowiki>:</nowiki>
swing*: [[Number]] (Optional, Default 0/locked) - Rotation in radians, between [[pi]] and [[pi]]<br>
::: [[Array]] - [type, spring, damping, forceLimit]<div class="_description">
<br>
:::; type<nowiki>:</nowiki>
Pyramid limit:<br>
:::: [[Number]] - MUST be 0 (#TODO acceleration drive implementation?)<br>
swing: [[Array]] - [(min, max)] - Same rotation in radians as the cone limit, but it can be asymetrical. Both are optional and default is 0/locked.<br>
:::; spring<nowiki>:</nowiki>
<br>
:::: [[Number]] - Same as springParameters above
Note that cone cannot be combined with pyramid, either both are cone or both are pyramid.<br>
:::; damping<nowiki>:</nowiki>
If the swing limit is [[pi]], the rotation around that axis is fully unlocked/free.<br>
:::: [[Number]] - Same as springParameters above
<br>
:::; forceLimit<nowiki>:</nowiki>
twistLimit: [[Array]] - [(twistLower, twistUpper, springParameters)]<br>
::::  [[Number]] - The maximum force this drive c an apply to the joint
twist is rotation about the Y (front/dir) axis, thus the roll.<br>
:; limitsAreForces<nowiki>:</nowiki>
Left and right twist limits can be configured independently.<br>
:: [[Boolean]] (Optional, Default: true) - NOT IMPLEMENTED #TODO?</div>
<br>
twist*: [[Number]] (Optional, Default: 0) - Rotation limit in radians, between -2[[pi]] and 2[[pi]]<br>
<br>
0 means twist is locked, and 2*pi means its completely unlocked<br>
<br><br>


drives: [[Array]] - [(angularTwistDrive, angularSwingDrive, angularSlerpDrive, linearXDrive, linearYDrive, linearZDrive, limitsAreForces)]<br>
|r1= [[Nothing]] - Do NOT depend on this staying nothing, it might change to be something.
Drives allow to apply force into the joint on any of the axes.<br>
Each drive is a spring, one end being on the joint, and the other end being on the target specified by the commands:<br>
[[setJointDrivePosition]] [[setJointDriveOrientation]] [[setJointDriveLinearVelocity]] [[setJointDriveAngularVelocity]]<br>
 
For rotational drives there are two variants, Swing+Twist or SLERP (Spherical Linear Interpolation)<br>
See https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/Joints.html#drives<br>
<br>
*Drive: [[Array]] - [type, spring, damping, forceLimit]<br>
<br>
type: [[Number]] - MUST be 0 (#TODO acceleration drive implementation?)<br>
spring: [[Number]] - Same as springParameters above<br>
damping: [[Number]] - Same as springParameters above<br>
forceLimit: [[Number]] - The maximum force this drive c an apply to the joint<br>
<br>
limitsAreForces: [[Boolean]] (Optional, Default: true) - NOT IMPLEMENTED #TODO?<br>


|x1=
|x1=

Revision as of 17:21, 25 June 2025

Hover & click on the images for description
Only available in Development branch(es) until its release with Arma 3 patch v2.22.

Description

Description:
🏗
This article is a work in progress!

Attaches a child object to a parent, similar to attachTo but instead of a rigid/forced attachment its using a PhysX joint.

For more information see NVIDIA docs.
Does NOT behave well in Multiplayer!
Groups:
Object Manipulation

Syntax

Syntax:
[parent, child] attachChild [jointType, localFrameParent, localFrameChild, miscFlags, jointDescription]
Parameters:
parent: Object - The parent object that another object is attached to. Must be a Transport vehicle like Car/Tank (Maybe helicopter/airplane works?).
child: Object - The object being attached onto the parent. Must be a Transport vehicle like Car/Tank (Maybe helicopter/airplane works?).
jointType: String - Currently only "6DOFJoint" and "RevoluteJoint" and "FixedJoint"
6DOFJoint
Allows to configure all axis (XYZ translation, Pitch/Yaw/Roll rotation) limits and drives.
RevoluteJoint
Only allows rotation around the X axis, a Revolute joint can also be implemented with a 6DOFJoint and the appropriate limits (internally it is implemented exactly like that)
FixedJoint
Limited in all axis, it essentially works like a PhysX based attachTo.
localFrameParent: Array - The Position and orientation, in parent's model-space of where the joint will be placed.
An Array of 3 elements [position, upPos, dirPos]
Each element can either be a Vector (3-element array of Number) or a Memory point name (String).


An important Caveat when using Vectors is that dir and up are not direction vectors, but positions.
Essentially, upPos/dirPos would be the model-space coordinates of where the memory point would be.
For example:
_jointPos = [0,0,0]; _vectorDir = [0,1,0]; _vectorUp = [0,0,1]; [_jointPos, _jointPos vectorAdd _vectorDir, _jointPos vectorAdd _vectorUp];
localFrameChild: Array - The Position and orientation, in child's model-space of where the joint will be placed.
miscFlags: Array - [(collisionEnabled, breakForce)]
collisionEnabled: Boolean (Optional, Default: false) - When false, disables collision between the two joint-ed objects
breakForce: Number (Optional, Default: -1)
limitsAreForces?
jointDescription: Array - This specifies the behavior/limits of the joint.
[(linearLimit, swingLimit, twistLimit, drives)]

Note that all are optional. Passing an empty array is equivalent to using a "FixedJoint" type

linearLimit
Array - Linear limit specifies the joints permitted translation along the XYZ axis.
There are three types of linear limits, fully locked, per-axis limit and distance limit.

Fully Locked:
[]
Empty array, will completely lock the XYZ translational axes, only allowing rotational movement (If allowed in the swing/twist limits)
Per axis:
[limitX, limitY, limitZ]
limit*:
Array - [lowerLimit, upperLimit, springParameters]
lowerLimit:
Number - The minimum permitted offset on the axis
upperLimit:
Number - The maximum permitted offset on the axis
upperLimit must be larger than lowerLimit
springParameters:
Array - [(restitution, spring, damping)]
All spring parameters are optional, but for the linear limits, atleast an empty array must be provided.
restitiution:
Number (Optional, Default: 0) - Must be between 0-1.
Controls the amount of bounce when the joint hits a limit.
A restitution value of 1.0 causes the joint to bounce back with the velocity which it hit the limit.
A value of zero causes the joint to stop dead.
NVIDIA docs
spring:
Number (Optional, Default: 0) - Must be 0 or greater.
if greater than zero, the limit is soft, i.e. a spring pulls the joint back to the limit
damping:
Number (Optional, Default: 0) - Must be 0 or greater. if spring is greater than zero, this is the damping of the limit spring
Distance Limit
[xLocked, yLocked, zLocked, distanceLimit, springParameters]
*Locked:
Boolean - Whether the axis is completely locked and no translation is allowed along it
distanceLimit:
Number - Distance on meters, as a radius/sphere around the joint.
swingLimit:
Array - [(swingX, swingZ, springParameters)]
All parameters are optional, the default is both swing axis being locked
Swing limit comes in two types, cone and pyramid. Which variant is used depends on the datatype inside the swing parameter
Note that cone cannot be combined with pyramid, either both are cone or both are pyramid.
If the swing limit is pi, the rotation around that axis is fully unlocked/free.
Cone limit:
swingX: Number (Optional, Default 0/locked) - The rotation around the X (right) axis, thus the pitch. Rotation in radians, between pi and pi.
swingZ: Number (Optional, Default 0/locked) - The rotation around the Z (up) axis, thus the yaw. Rotation in radians, between pi and pi.
Pyramid limit:
swingX: Array - [(min, max)] - Same rotation in radians as the cone limit, but it can be asymmetrical.
swingZ: Array - [(min, max)] - Same rotation in radians as the cone limit, but it can be asymmetrical.
twistLimit:
Array - [(twistLower, twistUpper, springParameters)]
Twist is rotation about the Y (front/dir) axis, thus the roll.
Left and right twist limits can be configured independently.
twist*:
Number (Optional, Default: 0) - Rotation limit in radians, between -2pi and 2pi
0 means twist is locked, and 2*pi means its completely unlocked
drives:
Array - [(angularTwistDrive, angularSwingDrive, angularSlerpDrive, linearXDrive, linearYDrive, linearZDrive, limitsAreForces)]
Drives allow to apply force into the joint on any of the axes.
Each drive is a spring, one end being on the joint, and the other end being on the target specified by the commands:
setJointDrivePosition setJointDriveOrientation setJointDriveLinearVelocity setJointDriveAngularVelocity
For rotational drives there are two variants, Swing+Twist or SLERP (Spherical Linear Interpolation)
See NVIDIA docs
*Drive:
Array - [type, spring, damping, forceLimit]
type:
Number - MUST be 0 (#TODO acceleration drive implementation?)
spring:
Number - Same as springParameters above
damping:
Number - Same as springParameters above
forceLimit:
Number - The maximum force this drive c an apply to the joint
limitsAreForces:
Boolean (Optional, Default: true) - NOT IMPLEMENTED #TODO?
Return Value:
Nothing - Do NOT depend on this staying nothing, it might change to be something.

Examples

Example 1:
Attach a Quad (varname towbar) to a HEMTT (varName vParent) and another HEMTT (varName vChild) to the Quad. Essentially using the Quad as a "towbar"
_parentPos = [0,-5,0]; // position on the hemtt _childPos = [0,1,-0.2]; // position on the quad _jointDescription = [ // Limits // Linear [], // Default is locked // Swing // [swing1 pitch, swing2 yaw, springParams] [ rad 20, // pitch rad 45 // yaw ], // Twist Roll // [twistLower, twistUpper, springParams] [], // Default is locked // Drives [] // Default are none ]; _params = [ "6DOFJoint", // From [pos,dir,up] [_parentPos, _parentPos vectorAdd [0, 1, 0], _parentPos vectorAdd [0, 0, 1]], // To [pos,dir,up] [_childPos, _childPos vectorAdd [0, 1, 0], _childPos vectorAdd [0, 0, 1]], // misc [collisions enabled] [false], _jointDescription ]; [vParent, towBar] attachChild _params; _parentPos = [0,-1,-0.2]; // Position on the quad _childPos = [0,5,0]; // Position on the hemtt _params = [ "6DOFJoint", // From [pos,dir,up] [_parentPos, _parentPos vectorAdd [0, 1, 0], _parentPos vectorAdd[0, 0, 1]], // To [pos,dir,up] [_childPos, _childPos vectorAdd [0, 1, 0], _childPos vectorAdd [0, 0, 1]], // misc [collisions enabled] [false], _jointDescription ]; [towBar, vChild] attachChild _params;
Example 2:
-no SQF code provided-
Example 3:
-no SQF code provided-
Example 4:
-no SQF code provided-
Example 5:
-no SQF code provided-

Additional Information

See also:
detachChild setJointDrivePosition setJointDriveOrientation setJointDriveLinearVelocity setJointDriveAngularVelocity

Notes

Report bugs on the Feedback Tracker and/or discuss them on the Arma Discord or on the Forums.
Only post proven facts here! Add Note