|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectartisynth.core.modelbase.ModelComponentBase
artisynth.core.modelbase.RenderableComponentBase
artisynth.core.mechmodels.MeshComponent
artisynth.core.mechmodels.SkinMeshBase
artisynth.core.femmodels.SkinMesh
public class SkinMesh
A MeshComponent that supports "skinning", in which the position of each mesh vertex is controlled by the position of one or more "master" components (such as Frames or FEM nodes).
SkinMesh
manages this skinning by assigning a
PointSkinAttachment
to each vertex within the mesh, which stores the
master components used to control the vertex position and computes that
position using the
computePosState()
method.
PointSkinAttachment
is an instance of PointAttachment
,
and when used by SkinMesh
to control vertex positions it does
not connect to any Point
component as a slave (i.e., getSlave()
returns null
.
However, PointSkinAttachments
can also
be used to attach a point or a marker to the "skin" of a
SkinMesh
, and so allow velocities to propagate from the master
components to the point, and forces to propagate from the point to the
masters.
Master components can currently include Frame
, FemNode3d
(within a specific FemModel3d
), and individual Particle
objects. The set of master components can vary from vertex to
vertex. PointSkinAttachment
maintains a set of
connections to each master component, each with a specified
weight, and computes the final vertex position as a weighted
sum of the positions computed for each connection. In pseudocode,
this can be expressed as:
vertexPos = 0; for (each connection c) { vertexPos += c.weight * c.connectionPos(); }
Frames
control vertex positions using various skinning
techniques known in the literature. These include linear, linear dual
quaternion, and iterative dual quaternion skinning. The technique used is
controlled by the getFrameBlending()
and setFrameBlending()
methods. Implementing these
techniques requires SkinMesh
to maintain additional information
for each Frame. Therefore it is necessary for all Frames used in skinning to
be registered with the SkinMesh using
addFrame()
.
FEM nodes can control vertex positions using linear combinations of
either their current position values, or their current displacements from the
rest position. It is also recommended that any FemModel used in skinning be
registered with the SkinMesh using
addFemModel()
,
although neither of the currently implemented FemNode
control
methods actually require this.
Finally, it is also possible to use a vertex's initial base
position to control a portion of its final position. Vertex base
positions are also used for Frame-based skinning. Vertex base
positions are set initially when a mesh is assigned to the skin.
Base positions can be queried and set using
getBasePosition()
and
setBasePosition()
, and can be reset
en mass using resetBasePositions()
.
Setting up a SkinMesh
involves three basic steps:
skinMesh = new SkinMesh (polyMesh); skinMesh.addFrame (rigidBody1); skinMesh.addFrame (rigidBody2); skinMesh.addFemModel (femModel1); skinMesh.computeDisplacementAttachments();Here,
computeDisplacementAttachments()
automatically computes an attachment for each vertex involving
all registered Frames and FemModels that contain a polygonal mesh.
The weights connecting each vertex to these master components is based
on their current distance to the vertex. Other functions for
computing attachments, based on different schemes, may be added
in the future.
Alternatively, the application may compute attachments directly. A sketch of the required code might look like this:
skinMesh.clearAttachments(); for (int i=0; i < skinMesh.numVertices(); i++) { Vertex3d vtx = skinMesh.getVertex (i); ... use vertex position to compute weights w1, w2, w3, w4 relating it to various master components ... PointSkinAttachment a = new PointSkinAttachment(); // add new connections: a.addFrameConnection (body1Index, w1); a.addFrameConnection (body2Index, w2); a.addFemDisplacementConnection (femNode4, w3); a.addFemDisplacementConnection (femNode6, w4); a.finalizeConnections(); skinMesh.addAttachment (a); }The initial call to
clearAttachments()
is necessary if the
skinMesh already contains attachments. Then for each vertex, master
components are determined, along with their associated weights, and an
attachment is created with master connections added using various
addXXXConnection()
methods followed by a call to finalizeConnections()
. The method
addFrameConnection()
specifies a Frame
master, which controls the vertex position
using the skinning technique returned by getFrameBlending()
. The Frame itself is specified using its
FrameInfo
structure within SkinMesh
, which
can be obtained
using getFrameInfo()
. The method addFemDisplacementConnection()
specifies a FemNode3d
as a master,
which controls the vertex position using its current displacement from its
own rest position. Other types of connections are possible; one should
consult the source code or documentation for PointSkinAttachment
.
When calculating attachment weights, an application will likely to need
access to the Frames and FemModels that are registered with the SkinMesh
(for example, to make distance queries on their surface meshes).
This can be done using methods such as numFrames()
, getFrame(int)
, numFemModels()
, and getFemModel()
.
Nested Class Summary | |
---|---|
class |
SkinMesh.BodyInfo
Base class for information about bodies (e.g., Frames or FemNodels) used to control the skinning. |
class |
SkinMesh.FemModelInfo
Contains information for each FemModel controlling this SkinMesh. |
static class |
SkinMesh.FrameBlending
Characterizes the blend mechanism used for the frame-based portion of the skinning. |
class |
SkinMesh.FrameInfo
Contains information for each frame controlling this SkinMesh. |
Nested classes/interfaces inherited from interface artisynth.core.mechmodels.Collidable |
---|
Collidable.DefaultCollidable |
Nested classes/interfaces inherited from interface artisynth.core.modelbase.ModelComponent |
---|
ModelComponent.NavpanelVisibility |
Nested classes/interfaces inherited from interface artisynth.core.modelbase.CompositeComponent |
---|
CompositeComponent.NavpanelDisplay |
Field Summary | |
---|---|
static SkinMesh.FrameBlending |
DEFAULT_FRAME_BLENDING
|
static double |
DQ_BLEND_TOLERANCE
|
static int |
DQ_MAX_BLEND_STEPS
|
static PropertyList |
myProps
|
Fields inherited from class artisynth.core.modelbase.ModelComponentBase |
---|
enforceUniqueCompositeNames, enforceUniqueNames, myNumber, NULL_OBJ, useCompactPathNames |
Fields inherited from interface artisynth.core.mechmodels.Collidable |
---|
Default, Deformable, RigidBody, Self |
Fields inherited from interface artisynth.core.util.TransformableGeometry |
---|
ARTICULATED, SIMULATING |
Fields inherited from interface maspack.render.GLRenderable |
---|
TRANSLUCENT, TWO_DIMENSIONAL |
Constructor Summary | |
---|---|
SkinMesh()
Creates an empty SkinMesh. |
|
SkinMesh(MeshBase mesh)
Creates a SkinMesh with a specified mesh. |
Method Summary | |
---|---|
void |
addAttachment(PointSkinAttachment a)
Adds an attachment to this SkinMesh. |
void |
addAttachment(PointSkinAttachment a,
boolean initBase)
Adds an attachment to this SkinMesh. |
void |
addFemModel(FemModel3d fem)
Registers a FemModel with this SkinMesh so that it can be used for skinning control. |
void |
addFrame(Frame frame)
Registers a Frame with this SkinMesh so that it can be used for skinning control. |
void |
applyForce(java.lang.Object orig,
Vector3d force)
Given the supplied force origin info and a force vector, apply the force (typically sets an external force) |
void |
clearAttachments()
Clears all the attachments associated with this SkinMesh. |
void |
computeDisplacementAttachments(double sigma)
Computes displacement-based attachments for each vertex attachment in this skin mesh. |
void |
computeWeights()
|
void |
connectToHierarchy()
Called by the system after this component is added to the component hierarchy (i.e., when it is added as a child of another CompositeComponent). |
CollisionData |
createCollisionData()
|
void |
disconnectFromHierarchy()
Called by the system after this component is removed from the component hierarchy (i.e., when it is removed as a child of its parent). |
java.util.List<SkinMesh.FemModelInfo> |
getAllFemModelInfo()
Returns the information structures of all FemModels that are currently registered with this SkinMesh. |
java.util.List<SkinMesh.FrameInfo> |
getAllFrameInfo()
Returns the information structures of all Frames that are currently registered with this SkinMesh. |
PropertyList |
getAllPropertyInfo()
Returns a list giving static information about all properties exported by this object. |
PointSkinAttachment |
getAttachment(int idx)
Returns the attachment for the idx-th vertex of this SkinMesh. |
Point3d |
getBasePosition(int idx)
Returns the base position for a specified vertex attachment in this SkinMesh. |
FemModel3d |
getFemModel(int idx)
Returns a FemModel that is currently registered with SkinMesh. |
int |
getFemModelIndex(FemModel fem)
Returns the index of a FemModelthat is currently registered with t this SkinMesh, or -1 if the FemModel is not registered. |
SkinMesh.FemModelInfo |
getFemModelInfo(int idx)
Returns an information structure for a FemModel that is currently registered with this SkinMesh. |
Frame |
getFrame(int idx)
Returns a Frame that is currently registered with SkinMesh. |
SkinMesh.FrameBlending |
getFrameBlending()
Returns the blend type for that part of the skinning that depends on frames. |
SkinMesh.FrameInfo |
getFrameInfo(Frame frame)
Returns the FrameInfo for a Frame that is currently registered with this SkinMesh, or null if the Frame is not registered. |
SkinMesh.FrameInfo |
getFrameInfo(int idx)
Returns an information structure for a Frame that is currently registered with this SkinMesh. |
double |
getMass()
|
java.lang.Object |
getOriginData(MouseRayEvent ray)
Constructs force origin storage data given a mouse ray (e.g. |
Point3d |
getOriginPoint(java.lang.Object data)
Determines the world-coordinate point to which force will be applied (used for determining magnitude of force) |
double |
getPointRenderRadius()
|
void |
getSoftReferences(java.util.List<ModelComponent> refs)
Appends all soft references for this component to a list. |
boolean |
hasFemModel(FemModel3d fem)
Returns true is a specified FemModel is currently registered with this SkinMesh. |
boolean |
hasFrame(Frame frame)
Returns true is a specified Frame is currently registered with this SkinMesh. |
boolean |
isCollidable()
|
boolean |
isPullable()
|
int |
numAttachments()
Returns the number of attachments currently in this SkinMesh. |
int |
numFemModels()
Returns the number of FemModels currently registered with this SkinMesh. |
int |
numFrames()
Returns the number of Frames currently registered with this SkinMesh. |
void |
scan(ReaderTokenizer rtok,
java.lang.Object ref)
Scans this element from a ReaderTokenizer. |
void |
setBasePosition(int idx,
Vector3d pos)
Sets the base position for a specified vertex attachment in the SkinMesh. |
void |
setFrameBlending(SkinMesh.FrameBlending type)
Sets the blend type for that part of the skinning that depends on frames. |
void |
setMesh(MeshBase mesh)
Sets the mesh associated with the this SkinMesh. |
void |
smoothWeights()
|
void |
smoothWeights(int networkDist)
|
void |
smoothWeights(SISOFunction weightFunction,
int networkDist)
Smooths weights according to a weighting function of distance. |
void |
transformGeometry(AffineTransform3dBase X,
TransformableGeometry topObject,
int flags)
Applies an affine transformation to the geometry of this object. |
void |
updateReferences(boolean undo,
java.util.Deque<java.lang.Object> undoInfo)
May be called by the system if any of the soft references for this component are removed from the the component hierarchy. |
void |
updateSlavePos()
Updates the mesh vertices to reflect the current position of the attached Frames, FemModels, and points. |
Methods inherited from class artisynth.core.mechmodels.SkinMeshBase |
---|
componentChanged, copy, findComponent, get, get, getByNumber, getNavpanelDisplay, getNavpanelVisibility, getNumberLimit, hierarchyContainsReferences, indexOf, numComponents, postscan, scaleDistance, setDisplayMode, setNavpanelDisplay, updateNameMap, updateSlaveVel |
Methods inherited from class artisynth.core.mechmodels.MeshComponent |
---|
createRenderProps, getMesh, getVertex, numVertices, prerender, render, render, scaleMass, setDefaultValues, setMesh, setMesh, transformGeometry, transformGeometry, updateBounds, updatePosition |
Methods inherited from class artisynth.core.modelbase.RenderableComponentBase |
---|
getRenderHints, getRenderProps, getSelection, isSelectable, numSelectionQueriesNeeded, setRenderProps, updateRenderProps |
Methods inherited from class artisynth.core.modelbase.ModelComponentBase |
---|
checkFlag, checkName, checkNameUniqueness, clearFlag, clone, createTempFlag, getChildren, getGrandParent, getHardReferences, getName, getNameRange, getNavpanelVisibility, getNumber, getParent, getProperty, hasChildren, hasState, isFixed, isMarked, isSelected, isWritable, makeValidName, makeValidName, notifyParentOfChange, printReferences, recursivelyContained, recursivelyContains, removeTempFlag, setFixed, setFlag, setMarked, setName, setNavpanelVisibility, setNavpanelVisibility, setNumber, setParent, setSelected, write |
Methods inherited from class java.lang.Object |
---|
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Methods inherited from interface artisynth.core.modelbase.ModelComponent |
---|
getHardReferences, getName, getNavpanelVisibility, getNumber, getParent, hasState, isFixed, isMarked, isSelected, notifyParentOfChange, postscan, setFixed, setMarked, setName, setNumber, setParent, setSelected |
Methods inherited from interface maspack.properties.HasProperties |
---|
getProperty |
Methods inherited from interface maspack.properties.HierarchyNode |
---|
getChildren, hasChildren |
Methods inherited from interface maspack.util.Scannable |
---|
isWritable, write |
Field Detail |
---|
public static SkinMesh.FrameBlending DEFAULT_FRAME_BLENDING
public static int DQ_MAX_BLEND_STEPS
public static double DQ_BLEND_TOLERANCE
public static PropertyList myProps
Constructor Detail |
---|
public SkinMesh()
public SkinMesh(MeshBase mesh)
Method Detail |
---|
public PropertyList getAllPropertyInfo()
HasProperties
getAllPropertyInfo
in interface HasProperties
getAllPropertyInfo
in class SkinMeshBase
public void setFrameBlending(SkinMesh.FrameBlending type)
public SkinMesh.FrameBlending getFrameBlending()
public int numAttachments()
numAttachments
in class SkinMeshBase
public void addAttachment(PointSkinAttachment a)
public void addAttachment(PointSkinAttachment a, boolean initBase)
initBase
is
true, then the attachment's base position is set to the current vertex
position. The number of attachments cannot exceed the current number of
mesh vertices.
public void clearAttachments()
public PointSkinAttachment getAttachment(int idx)
getAttachment
in class SkinMeshBase
idx
- index of the vertex for which the attachment is desired.
Must be less that numAttachments()
.public void setMesh(MeshBase mesh)
setMesh
in class MeshComponent
public void addFrame(Frame frame)
frame
- Frame to be registeredpublic boolean hasFrame(Frame frame)
frame
- Frame to be queriedpublic int numFrames()
public SkinMesh.FrameInfo getFrameInfo(int idx)
idx
- identities the Frame; must be between 0 and
the number returned by numFrames()
.public java.util.List<SkinMesh.FrameInfo> getAllFrameInfo()
public Frame getFrame(int idx)
idx
- identities the Frame; must be between 0 and
the number returned by numFrames()
.public SkinMesh.FrameInfo getFrameInfo(Frame frame)
frame
- Frame whose FrameInfo is desiredpublic void addFemModel(FemModel3d fem)
fem
- FemModel to be registeredpublic boolean hasFemModel(FemModel3d fem)
fem
- FemModel to be queriedpublic int numFemModels()
public SkinMesh.FemModelInfo getFemModelInfo(int idx)
idx
- identities the FemModel; must be between 0 and
the number returned by numFemModels()
.public java.util.List<SkinMesh.FemModelInfo> getAllFemModelInfo()
public FemModel3d getFemModel(int idx)
idx
- identities the FemModel; must be between 0 and
the number returned by numFemModels()
.public int getFemModelIndex(FemModel fem)
fem
- FemModel whose index is desiredpublic Point3d getBasePosition(int idx)
idx
- index of the attachment. Must be less than
numAttachments()
.public void setBasePosition(int idx, Vector3d pos)
idx
- index of the attachment. Must be less than
numAttachments()
.pos
- new base positonpublic void smoothWeights(SISOFunction weightFunction, int networkDist)
weightFunction
- single-input single-output function of distance
to use as weightsnetworkDist
- number of paths to traverse to collect verticespublic void smoothWeights(int networkDist)
public void smoothWeights()
public void computeWeights()
public void computeDisplacementAttachments(double sigma)
Bodies further away have a lower weighting. If sigma
is non-positive, the weighting is determined using an inverse-square
attenuation. Otherwise, the weighting is determined using a
Gaussian attention controlled by sigma
.
sigma
- if greater than 0, specifies a Gaussian weighting
attenuation.public void updateSlavePos()
updateSlavePos
in interface HasSlaveObjects
updateSlavePos
in class SkinMeshBase
public void transformGeometry(AffineTransform3dBase X, TransformableGeometry topObject, int flags)
TransformableGeometry
topComponent
should be the component for which the method
was initially invoked. The variable flags
provides
information about the context in which the transformation is
being applied. At present, the available flags are
TransformableGeometry.SIMULATING
and TransformableGeometry.ARTICULATED
.
transformGeometry
in interface TransformableGeometry
transformGeometry
in class SkinMeshBase
X
- affine transformationtopObject
- component on which the method was initially invokedflags
- provides information about the context in which the
transformation is being applied.public void scan(ReaderTokenizer rtok, java.lang.Object ref) throws java.io.IOException
ModelComponentBase
write
.
scan
in interface ModelComponent
scan
in interface Scannable
scan
in class SkinMeshBase
rtok
- Tokenizer from which to scan the elementref
- optional reference object which can be used for resolving references to
other objects
java.io.IOException
- if an I/O or formatting error occuredpublic void connectToHierarchy()
ModelComponentBase
When this method is called, ModelComponent.getParent()
will return
the new parent component; the system will have set this beforehand.
connectToHierarchy
in interface ModelComponent
connectToHierarchy
in class ModelComponentBase
public void disconnectFromHierarchy()
ModelComponentBase
When this
method is called, ModelComponent.getParent()
will still return this original
parent component; the system will set this to null
after.
disconnectFromHierarchy
in interface ModelComponent
disconnectFromHierarchy
in class ModelComponentBase
public void getSoftReferences(java.util.List<ModelComponent> refs)
updateReferences()
method will
be called to update its internal reference information.
getSoftReferences
in interface ModelComponent
getSoftReferences
in class ModelComponentBase
refs
- list to which soft references are appendedpublic void updateReferences(boolean undo, java.util.Deque<java.lang.Object> undoInfo)
undo
equal to false
,
this component should then examine its soft references and
use ComponentUtils.isConnected()
to determine which of them have been disconnected from the hierarchy.
Disconnected references should be removed, and sufficient information
should be appended to undoInfo
to allow this update
to be undone if this method is called later with undo
equal to true
. When undoing an update, the undo
information should be removed from the front of undoInfo
.
updateReferences
in interface ModelComponent
updateReferences
in class ModelComponentBase
undo
- if true
, indicates that the most
recent reference update should be undone, using the supplied
undo information.undoInfo
- if undo
is false
, should be used
to store information allowing the reference update to be undone.
Otherwise, if undo
is true
, then this
supplied information to undo the most recent update.public boolean isPullable()
isPullable
in interface PullController.Pullable
public java.lang.Object getOriginData(MouseRayEvent ray)
PullController.Pullable
getOriginData
in interface PullController.Pullable
public Point3d getOriginPoint(java.lang.Object data)
PullController.Pullable
getOriginPoint
in interface PullController.Pullable
public double getPointRenderRadius()
getPointRenderRadius
in interface PullController.Pullable
public void applyForce(java.lang.Object orig, Vector3d force)
PullController.Pullable
applyForce
in interface PullController.Pullable
public CollisionData createCollisionData()
createCollisionData
in interface Collidable
public boolean isCollidable()
isCollidable
in interface Collidable
public double getMass()
getMass
in interface Collidable
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |