As mentioned above, skin meshes within ArtiSynth are implemented using the SkinMeshBody component. Applications typically create a skin mesh in code according to the following steps:
Create an instance of SkinMeshBody and assign its underlying mesh, usually within the constructor;
Add references to the required master bodies;
Compute the master body connections
This is illustrated by the following example:
Master body references are added using
When all the master bodies have been added, the method
computeAllVertexConnections() computes the weighted connections to each vertex. The connection weights for each vertex are determined by a weighting function, based on the distances between the vertex and each master body. The default weighting function is inverse-square weighting, which first computes a set of raw weights according to
where is the minimum master body distance, and then normalizes these to determine :
Other weighting functions can be specified, as described in Section 8.3.
SkinMeshBody provides the following set of methods to set and query its master body configuration:
When a Frame master body is added using addMasterBody(), its initial, or base, pose (corresponding to and in Section 8.1) is set from its current pose. If necessary, applications can later query and reset the base pose using the methods getBasePose() and setBasePose().
Internally, each vertex is connected to the master bodies by a
contains a list
PointSkinAttachment.SkinConnection components describing each master connection. Applications can obtain the PointSkinAttachment for each vertex using the method
where vidx is the vertex index, which must be in the range 0 to numv-1, with numv the number of vertices as returned by numVertices(). Methods also exist to query and set each vertex’s base (i.e., initial) position :
An example of skinning a mesh over two rigid bodies is given by artisynth.demos.tutorial.RigidBodySkinning. It consists of a SkinMeshBody placed around two rigid bodies connected by a hinge joint to form a toy “arm”, with a Muscle added to move the lower body with respect to the upper. The code for the build() method is given below:
A MechModel is created in the usual way (lines 2-7). To this is added a very simple toy “arm” consisting of an upper and lower body connected by a hinge joint (lines 9-27), with a simple point-to-point muscle attached between frame markers on the upper and lower bodies to provide a means of moving the arm (lines 29-36). Creation of the arm bodies uses an addBody() method which is not shown.
The mesh to be skinned is an ellipsoid, created using the FemFactory method createSphere() to produce a spherical mesh which is then scaled and repositioned (lines 38-43). The skin body itself is then created around this mesh, with the upper and lower bodies assigned as master bodies and the connections computed using computeAllVertexConnections() (lines 45-50).
A control panel is added to allow control over the muscle’s excitation as well as the skin body’s frameBlending property (lines 52-56). Finally, render properties are set (lines 58-67): the skin mesh is made transparent by setting its faceStyle and drawEdges properties to NONE and true, respectively, with cyan colored edges; the muscle is rendered as a red spindle; the joint is drawn as a blue cylinder and the bodies are colored light grey.
To run this example in ArtiSynth, select All demos > tutorial > RigidBodySkinning from the Models menu. The model should load and initially appear as in Figure 8.3 (left). When running the simulation, the arm can be flexed by adjusting the muscle excitation property in the control panel, causing the skin mesh to deform (Figure 8.3, middle). Changing the frameBlending property from its default value of LINEAR to DUAL_QUATERNION_LINEAR causes the mesh deformation to become fatter and less prone to creasing (Figure 8.3, right).