1
0
KF2-Dev-Scripts/Engine/Classes/SkeletalMeshComponent.uc
2022-05-11 18:13:25 +03:00

1872 lines
73 KiB
Ucode

/**
* Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
*/
class SkeletalMeshComponent extends MeshComponent
native(SkeletalMesh)
noexport
dependson(AnimNode)
hidecategories(Object)
config(Engine)
editinlinenew;
/** The skeletal mesh used by this component. */
var() SkeletalMesh SkeletalMesh;
/** The SkeletalMeshComponent that this one is possibly attached to. */
var SkeletalMeshComponent AttachedToSkelComponent;
/**
* This should point to the AnimTree in a content package.
* BeginPlay on this SkeletalMeshComponent will instance (copy) the tree and assign the instance to the Animations pointer.
*/
var() const AnimTree AnimTreeTemplate;
/**
* This is the unique instance of the AnimTree used by this SkeletalMeshComponent.
* THIS SHOULD NEVER POINT TO AN ANIMTREE IN A CONTENT PACKAGE.
*/
var() const editinline export AnimNode Animations <MaxPropertyDepth=3>;
/** Array of all AnimNodes in entire tree, in the order they should be ticked - that is, all parents appear before a child. */
var const transient array<AnimNode> AnimTickArray;
/** Special Array of nodes that should always be ticked, even when not relevant. */
var const transient array<AnimNode> AnimAlwaysTickArray;
/** Anim nodes relevancy status. Matching AnimTickArray size and indices. */
var const transient array<INT> AnimTickRelevancyArray;
/** Anim nodes weights. Matching AnimTickArray size and indices. */
var const transient array<FLOAT> AnimTickWeightsArray;
/** Linear Array for ticking SkelControls faster */
var const transient Array<SkelControlBase> SkelControlTickArray;
/**
* Physics and collision information used for this SkeletalMesh, set up in PhAT.
* This is used for per-bone hit detection, accurate bounding box calculation and ragdoll physics for example.
*/
var() const PhysicsAsset PhysicsAsset;
/**
* Any instanced physics engine information for this SkeletalMeshComponent.
* This is only required when you want to run physics or you want physical interaction with this skeletal mesh.
*/
var const transient editinline export PhysicsAssetInstance PhysicsAssetInstance;
// NVCHANGE_BEGIN: JCAO - Add the seperated PhysicsAsset for flex
/**
* Physics and collision information used for this SkeletalMesh, set up in PhAT.
* This is used for flex when you felt your main PhysicsAsset is too complicated for flex, you could create simple one here.
*/
var() const PhysicsAsset PhysicsAssetForFlex;
/**
* Any instanced physics engine information for this SkeletalMeshComponent.
* This is only required when you want to run flex and you need another PhysicsAsset to define the physics for flex.
*/
var const transient editinline export PhysicsAssetInstance PhysicsAssetInstanceForFlex;
var transient bool bUpdateFlexKinematicBonesFromAnimation;
// NVCHANGE_END: JCAO - Add the seperated PhysicsAsset for flex
/**
* Contains a pointer to the active APEX clothing instance.
*/
var const native transient pointer ApexClothing;
/**
* Enum to define how to scale max distance
* @see SetApexClothingMaxDistanceScale
*/
enum EMaxDistanceScaleMode
{
/** Clothing MaxDistances are reduced by mulitplication with the scale value */
MDSM_Multiply,
/** Clothing MaxDistances are reduced by subtracting the value "scale * biggest maxDistance" */
MDSM_Substract
};
/**
* Influence of rigid body physics on the mesh's pose (0.0 == use only animation, 1.0 == use only physics)
*/
var() interp float PhysicsWeight;
/** Used to scale speed of all animations on this skeletal mesh. */
var() float GlobalAnimRateScale;
/**
* Allows adjusting the desired streaming distance of streaming textures that uses UV 0.
* 1.0 is the default, whereas a higher value makes the textures stream in sooner from far away.
* A lower value (0.0-1.0) makes the textures stream in later (you have to be closer).
*/
var() float StreamingDistanceMultiplier;
var native transient const pointer MeshObject;
var() Color WireframeColor;
/** Temporary array of of component-space bone matrices, update each frame and used for rendering the mesh. */
var native transient const array<AnimNode.BoneAtom> SpaceBases;
/** Temporary array of local-space (ie relative to parent bone) rotation/translation for each bone. */
var native transient const array<AnimNode.BoneAtom> LocalAtoms;
/** Cached Bones, for performance. */
var native transient const array<AnimNode.BoneAtom> CachedLocalAtoms;
var native transient const array<AnimNode.BoneAtom> CachedSpaceBases;
/** When updated at low frequency, rate of update.
* For example if set to 3, animations will be updated once every three frames.
* if games runs at 30 FPS, that's 10 FPS.
* Not recommended to change during gameplay. */
//@zombie_ps4_begin
var const INT LowUpdateFrameRate;
//@zombie_ps4_end
/** Temporary array of bone indices required this frame. Filled in by UpdateSkelPose. */
var native const transient Array<byte> RequiredBones;
/** Required Bones array, re-ordered for 3 pass skeleton composing */
var native const transient Array<Byte> ComposeOrderedRequiredBones;
/**
* If set, this SkeletalMeshComponent will not use its Animations pointer to do its own animation blending, but will
* use the SpaceBases array in the ParentAnimComponent. This is used when constructing a character using multiple skeletal meshes sharing the same
* skeleton within the same Actor.
*/
var() const SkeletalMeshComponent ParentAnimComponent;
/**
* Mapping between bone indices in this component and the parent one. Each element is the index of the bone in the ParentAnimComponent.
* Size should be the same as SkeletalMesh.RefSkeleton size (ie number of bones in this skeleton).
*/
var native transient const array<int> ParentBoneMap;
/**
* The set of AnimSets that will be looked in to find a particular sequence, specified by name in an AnimNodeSequence.
* Array is search from last to first element, so you can replace a particular sequence but putting a set containing the new version later in the array.
* You will need to call SetAnim again on nodes that may be affected by any changes you make to this array.
*/
var() array<AnimSet> AnimSets;
/**
* Temporary array of AnimSets that are used as a backup target when the engine needs to temporarily modify the
* actor's animation set list. (e.g. Matinee playback)
*/
var native transient const array<AnimSet> TemporarySavedAnimSets;
// Morph targets
/**
* Array of MorphTargetSets that will be looked in to find a particular MorphTarget, specified by name.
* It is searched in the same way as the AnimSets array above.
*/
var() array<MorphTargetSet> MorphSets;
/** Struct used to indicate one active morph target that should be applied to this SkeletalMesh when rendered. */
struct ActiveMorph
{
/** The morph target that we want to apply. */
var MorphTarget Target;
/** Strength of the morph target, between 0.0 and 1.0 */
var float Weight;
};
/** Array indicating all active MorphTargets. This array is updated inside UpdateSkelPose based on the AnimTree's st of MorphNodes. */
var transient array<ActiveMorph> ActiveMorphs;
/** Array indicating all active MorphTargets. This array is updated inside UpdateSkelPose based on the AnimTree's st of MorphNodes. */
var transient array<ActiveMorph> ActiveCurveMorphs;
/** Map of morph target to name **/
var const native map{FName, UMorphTarget*} MorphTargetIndexMap;
// Attachments.
struct Attachment
{
var() editinline ActorComponent Component;
var() name BoneName;
var() vector RelativeLocation;
var() rotator RelativeRotation;
var() vector RelativeScale;
structdefaultproperties
{
RelativeScale=(X=1,Y=1,Z=1)
}
};
var duplicatetransient const array<Attachment> Attachments;
var transient const array<byte> SkelControlIndex;
var transient const array<byte> PostPhysSkelControlIndex;
/** If 0, auto-select LOD level. if >0, force to (ForcedLodModel-1). */
var() int ForcedLodModel;
/**
* This is the min LOD that this component will use. (e.g. if set to 2 then only 2+ LOD Models will be used.) This is useful to set on
* meshes which are known to be a certain distance away and still want to have better LODs when zoomed in on them.
**/
var() int MinLodModel;
var int PredictedLODLevel;
var int OldPredictedLODLevel; // LOD level from previous frame, so we can detect changes in LOD to recalc required bones
/** If MaxDistanceFactor goes below this value (and it is non 0), start playing animations at a lower frame rate */
var() float AnimationLODDistanceFactor;
/** Rate of update for skeletal meshes that are below AnimationLODDistanceFactor. For example if set to 3, animations will be updated once every three frames. */
var() int AnimationLODFrameRate;
/** High (best) DistanceFactor that was desired for rendering this SkeletalMesh last frame. Represents how big this mesh was in screen space */
var const float MaxDistanceFactor;
/** Index of the chunk to preview... If set to -1, all chunks will be rendered */
var editoronly transient int ChunkIndexPreview;
/** Index of the section to preview... If set to -1, all section will be rendered */
var editoronly transient int SectionIndexPreview;
var int bForceWireframe; // Forces the mesh to draw in wireframe mode.
/** If true, force the mesh into the reference pose - is an optimization. */
var int bForceRefpose;
/** If bForceRefPose was set last tick. */
var int bOldForceRefPose;
/** Skip UpdateSkelPose. */
var() bool bNoSkeletonUpdate;
/** Draw the skeleton hierarchy for this skel mesh. */
var int bDisplayBones;
/** Bool that enables debug drawing of the skeleton before it is passed to the physics. Useful for debugging animation-driven physics. */
var int bShowPrePhysBones;
var int bHideSkin;
var int bForceRawOffset;
var int bIgnoreControllers;
var int bTransformFromAnimParent;
var const transient int TickTag;
var const transient int InitTag;
var const transient int CachedAtomsTag;
/**
* Only instance Root Bone rigid body for physics. Mostly used by Vehicles.
* Other Rigid Bodies are ignored for physics, but still considered for traces.
*/
var const int bUseSingleBodyPhysics;
var transient int bRequiredBonesUpToDate;
/**
* If non-zero, skeletal mesh component will not update kinematic bones and bone springs when distance factor is greater than this (or has not been rendered for a while).
* This also turns off BlockRigidBody, so you do not get collisions with 'left behind' ragdoll setups. Items will fall through
* the world if you move too far away from them and they are in RigigBody.
*/
var float MinDistFactorForKinematicUpdate;
/** Used to keep track of how many frames physics has been asleep for (when using PHYS_RigidBody). */
var transient int FramesPhysicsAsleep;
/** <2 means no skip, 2 means every other frame, 3 means 1 out of three frames, etc */
var const transient int SkipRateForTickAnimNodesAndGetBoneAtoms;
/** If TRUE, we will not tick the anim nodes */
var const transient bool bSkipTickAnimNodes;
/** If TRUE, we will not call GetBonesAtoms, and instead use cached data */
var const transient bool bSkipGetBoneAtoms;
/** If TRUE, then bSkipGetBoneAtoms is also true; we will interpolate cached data */
var const transient bool bInterpolateBoneAtoms;
/** If TRUE, there is at least one body in the current PhysicsAsset with a valid bone in the current SkeletalMesh */
var const transient bool bHasValidBodies;
/**
* When true, if owned by a PHYS_RigidBody Actor, skip all update (bones and bounds) when physics are asleep. This is a very top level
* optimization flag for things we know are just physics (e.g. Kassets). Lots of things have physics on them that are asleep while the
* actor moves around the level and then are woken up. Setting this flag to true will stop those actors from having any updates which is not
* what we want in the general case.
*/
var bool bSkipAllUpdateWhenPhysicsAsleep;
/** When true, skip using the physics asset etc. and always use the fixed bounds defined in the SkeletalMesh. */
var() bool bComponentUseFixedSkelBounds;
/**
* When true, we will just using the bounds from our ParentAnimComponent. This is useful for when we have a Mesh Parented
* to the main SkelMesh (e.g. outline mesh or a full body overdraw effect that is toggled) that is always going to be the same
* bounds as parent. We want to do no calculations in that case.
*/
var() bool bUseBoundsFromParentAnimComponent;
/** If TRUE, when updating bounds from a PhysicsAsset, consider _all_ BodySetups, not just those flagged with bConsiderForBounds. */
var() bool bConsiderAllBodiesForBounds;
/** If true, update skeleton/attachments even when our Owner has not been rendered recently
* @note if this is false, bone information may not be accurate, so be careful setting this to false if bone info is relevant to gameplay
* @note you can use ForceSkelUpdate() to force an update
* @note: In the output from SHOWSKELCOMPTICKTIME you want UpdatePoseTotal to be 0 when this is FALSE for a specific component
*/
var() bool bUpdateSkelWhenNotRendered;
/** If true, do not apply any SkelControls when owner has not been rendered recently. */
var bool bIgnoreControllersWhenNotRendered;
/** If true, tick anim nodes even when our Owner has not been rendered recently */
var bool bTickAnimNodesWhenNotRendered;
/** If this is true, we are not updating kinematic bones and motors based on animation because the skeletal mesh is too far from any viewer. */
var const bool bNotUpdatingKinematicDueToDistance;
/** force root motion to be discarded, no matter what the AnimNodeSequence(s) are set to do */
var() bool bForceDiscardRootMotion;
/** Call RootMotionProcessed notification on Owner */
var() bool bNotifyRootMotionProcessed;
/**
* if TRUE, notify owning actor of root motion mode changes.
* This calls the Actor.RootMotionModeChanged() event.
* This is useful for synchronizing movements.
* For intance, when using RMM_Translate, and the event is called, we know that root motion will kick in on next frame.
* It is possible to kill in-game physics, and then use root motion seemlessly.
*/
var bool bRootMotionModeChangeNotify;
/**
* if TRUE, the event RootMotionExtracted() will be called on this owning actor,
* after root motion has been extracted, and before it's been used.
* This notification can be used to alter extracted root motion before it is forwarded to physics.
*/
var bool bRootMotionExtractedNotify;
/** Flag set when processing root motion. */
var transient bool bProcessingRootMotion;
/** If true, FaceFX will not automatically create material instances. */
var() bool bDisableFaceFXMaterialInstanceCreation;
/** If true, disable FaceFX entirely for this component */
var() bool bDisableFaceFX;
/** If true, AnimTree has been initialised. */
var const transient bool bAnimTreeInitialised;
/** If TRUE, UpdateTransform will always result in a call to MeshObject->Update. */
var private transient bool bForceMeshObjectUpdate;
/**
* Indicates whether this SkeletalMeshComponent should have a physics engine representation of its state.
* @see SetHasPhysicsAssetInstance
*/
var() const bool bHasPhysicsAssetInstance;
/** If we are running physics, should we update bFixed bones based on the animation bone positions. */
var() bool bUpdateKinematicBonesFromAnimation;
/**
* If we should pass joint position to joints each frame, so that they can be used by motorized joints to drive the
* ragdoll based on the animation.
*/
var() bool bUpdateJointsFromAnimation;
/** Indicates whether this SkeletalMeshComponent is currently considered 'fixed' (ie kinematic) */
var const bool bSkelCompFixed;
/** Used for consistency checking. Indicates that the results of physics have been blended into SpaceBases this frame. */
var const bool bHasHadPhysicsBlendedIn;
/**
* If true, attachments will be updated twice a frame - once in Tick and again when UpdateTransform is called.
* This can resolve some 'frame behind' issues if an attachment need to be in the correct location for it's Tick, but at a cost.
*/
var() bool bForceUpdateAttachmentsInTick;
/** Enables blending in of physics bodies with the bAlwaysFullAnimWeight flag set. (e.g. hair and other flappy bits!)*/
var transient bool bEnableFullAnimWeightBodies;
/**
* If true, when this skeletal mesh overlaps a physics volume, each body of it will be tested against the volume, so only limbs
* actually in the volume will be affected. Useful when gibbing bodies.
*/
var() bool bPerBoneVolumeEffects;
/**
* If true, use per-bone motion blur on this skeletal mesh.
*/
var() bool bPerBoneMotionBlur;
/** If true, will move the Actors Location to match the root rigid body location when in PHYS_RigidBody. */
var() bool bSyncActorLocationToRootRigidBody;
/** If TRUE, force usage of raw animation data when animating this skeletal mesh; if FALSE, use compressed data. */
var const bool bUseRawData;
/** Disable warning when an AnimSequence is not found. FALSE by default. */
var bool bDisableWarningWhenAnimNotFound;
/** if set, components that are attached to us have their bOwnerNoSee and bOnlyOwnerSee properties overridden by ours */
var bool bOverrideAttachmentOwnerVisibility;
/** if TRUE, when detach, send message to renderthread to delete this component from hit mask list **/
var const transient bool bNeedsToDeleteHitMask;
/** pauses this component's animations (doesn't tick them) */
var bool bPauseAnims;
/** If true, DistanceFactor for this SkeletalMeshComponent will be added to global chart. */
var bool bChartDistanceFactor;
/** If TRUE, line checks will test against the bounding box of this skeletal mesh component and return a hit if there is a collision. */
var bool bEnableLineCheckWithBounds;
/** Whether or not we can highlight selected sections - this should really only be done in the editor */
var transient bool bCanHighlightSelectedSections;
/** Update Morph when ParentAnimComponent exists **/
var() bool bUpdateMorphWhenParentAnimComponentExists;
/** If bEnableLineCheckWithBounds is TRUE, scale the bounds by this value before doing line check. */
var vector LineCheckBoundsScale;
// CLOTH bools
/**
* Whether cloth simulation should currently be used on this SkeletalMeshComponent.
* @see SetEnableClothSimulation
*/
var(Cloth) const bool bEnableClothSimulation;
/** Turns off all cloth collision so not checks are done (improves performance). */
var(Cloth) const bool bDisableClothCollision;
/** If true, cloth is 'frozen' and no simulation is taking place for it, though it will keep its shape. */
var(Cloth) const bool bClothFrozen;
/** If true, cloth will automatically have bClothFrozen set when it is not rendered, and have it turned off when it is seen. */
var(Cloth) bool bAutoFreezeClothWhenNotRendered;
/** If true, cloth will be awake when a level is started, otherwise it will be instantly put to sleep. */
var(Cloth) bool bClothAwakeOnStartup;
/** It true, clamp velocity of cloth particles to be within ClothBaseVelClampRange of Base velocity. */
var(Cloth) bool bClothBaseVelClamp;
/** It true, interp velocity of cloth particles towards Base velocity, using ClothBaseVelClampRange as the interp rate (0..1). */
var(Cloth) bool bClothBaseVelInterp;
/** If true, fixed verts of the cloth are attached in the physics to the physics body that this components actor is attached to. */
var(Cloth) bool bAttachClothVertsToBaseBody;
/** Whether this cloth is on a non-animating static object. */
var(Cloth) bool bIsClothOnStaticObject;
/** Whether we've updated fixed cloth verts since last attachment. */
var bool bUpdatedFixedClothVerts;
/** Whether should do positional box dampening */
var(Cloth) bool bClothPositionalDampening;
/** Whether wind direction is relative to owner rotation or not */
var(Cloth) bool bClothWindRelativeToOwner;
/**
* TRUE if mesh has been recently rendered, FALSE otherwise
*/
var transient bool bRecentlyRendered;
/** Should anim sequence nodes cache the calculated values when not actually playing an animation? */
var bool bCacheAnimSequenceNodes;
/** If TRUE, update the instanced vertex influences for this mesh during the next update */
var const transient bool bNeedsInstanceWeightUpdate;
/** If TRUE, always use instanced vertex influences for this mesh */
var const transient bool bAlwaysUseInstanceWeights;
/** TRUE if it needs to rebuild the required bones array for multi pass compose */
var const transient bool bUpdateComposeSkeletonPasses;
/** Flag to remember if cache saved is valid or not to make sure Save/Restore always happens with a pair **/
var native transient const bool bValidTemporarySavedAnimSets;
/** Usage cases for toggling vertex weights */
enum EInstanceWeightUsage
{
/** Weights are swapped for a subset of vertices. Requires a unique weights vertex buffer per skel component instance. */
IWU_PartialSwap,
/** Weights are swapped for ALL vertices. Shares a weights vertex buffer for all skel component instances. */
IWU_FullSwap
};
/**
* Set of bones which will be used to find vertices to switch to using instanced influence weights
* instead of the default skeletal mesh weighting.
*/
struct BonePair
{
var name Bones[2];
};
var native transient const array<BonePair> InstanceVertexWeightBones;
/** LOD specific setup for the skeletal mesh component */
struct SkelMeshComponentLODInfo
{
/** Material corresponds to section. To show/hide each section, use this **/
var const array<bool> HiddenMaterials;
var const bool bNeedsInstanceWeightUpdate;
var const bool bAlwaysUseInstanceWeights;
/** Whether the instance weights are used for a partial/full swap */
var const transient EInstanceWeightUsage InstanceWeightUsage;
/** Current index into the skeletal mesh VertexInfluences for the current LOD */
var const transient int InstanceWeightIdx;
};
var const transient array<SkelMeshComponentLODInfo> LODInfo;
// CLOTH
/** The state of the LocalToWorld pos at the point the cloth was frozen. */
var const vector FrozenLocalToWorldPos;
/** The state of the LocalToWorld rotation at the point the cloth was frozen. */
var const rotator FrozenLocalToWorldRot;
/** Constant force applied to all vertices in the cloth. */
var(Cloth) const vector ClothExternalForce;
/** 'Wind' force applied to cloth. Force on each vertex is based on the dot product between the wind vector and the surface normal. */
var(Cloth) vector ClothWind;
/** The time it takes for the cloth to reach the wind velocity. A value of .01 should get you a quick response. Setting this value to 0.0 turns the wind off. */
var(Cloth) float ClothWindBlendTime;
// NVCHANGE_BEGIN: JCAO - Add noise/variation for cloth wind
/** Specifies the deviation in degrees of the vertical and horizontal wind direction */
var (Cloth) float ClothWindDirectionDeviationAngle;
/** The period of each sinusoidal cycle of the wind oscillation in seconds. */
var (Cloth) float ClothWindDirectionOscillationPeriod;
/** The deviation in the strength of the wind */
var (Cloth) float ClothWindStrengthDeviationPercentage;
/** The period of each sinusoidal cycle of the wind strength oscillation in seconds. */
var (Cloth) float ClothWindStrengthOscillationPeriod;
var transient native pointer ClothWindDirectionVO1;
var transient native pointer ClothWindDirectionVO2;
var transient native pointer ClothWindStrengthVO;
var transient native Matrix ClothWindDirectionMatrix;
var transient native float ClothWindStrength;
// NVCHANGE_END: JCAO - Add noise/variation for cloth wind
/**
* If bClothBaseVelClamp is TRUE, amount of variance from base's velocity the cloth is allowed.
* If bClothBaseVelInterp is TRUE, how fast cloth verts are pushed towards base velocity (0..1)
*/
var(Cloth) vector ClothBaseVelClampRange;
/** How much to blend in results from cloth simulation with results from regular skinning. */
var(Cloth) float ClothBlendWeight;
/** Cloth blend weight, controlled by distance from camera. */
var float ClothDynamicBlendWeight;
/** Distance factor below which cloth should be fully animated. -1.0 indicates always physics. */
var(Cloth) float ClothBlendMinDistanceFactor;
/** Distance factor above which cloth should be fully simulated. */
var(Cloth) float ClothBlendMaxDistanceFactor;
/** Distance from the owner in relative frame (max == pos XYZ, min == neg XYZ) */
var(Cloth) Vector MinPosDampRange, MaxPosDampRange;
/** Dampening scale applied to cloth particle velocity when approaching boundaries of *PosDampRange */
var(Cloth) Vector MinPosDampScale, MaxPosDampScale;
var const native transient pointer ClothSim;
var const native transient int SceneIndex;
var const array<vector> ClothMeshPosData;
var const array<vector> ClothMeshNormalData;
var const array<int> ClothMeshIndexData;
var int NumClothMeshVerts;
var int NumClothMeshIndices;
/** Cloth parent indices contain the index of the original vertex when a vertex is created during tearing.
* If it is an original vertex then the parent index is the same as the vertex index.
*/
var const array<int> ClothMeshParentData;
var int NumClothMeshParentIndices;
/** buffers used for reverse lookups to unweld vertices to support wrapped UVs. */
var const native transient array<vector> ClothMeshWeldedPosData;
var const native transient array<vector> ClothMeshWeldedNormalData;
var const native transient array<int> ClothMeshWeldedIndexData;
/** flags to indicate which buffers were recently updated by the cloth simulation. */
var int ClothDirtyBufferFlag;
/** Enum indicating what type of object this cloth should be considered for rigid body collision. */
var(Cloth) const ERBCollisionChannel ClothRBChannel;
/** Types of objects that this cloth will collide with. */
var(Cloth) const RBCollisionChannelContainer ClothRBCollideWithChannels;
/** How much force to apply to cloth, in relation to the force(from a force field) applied to rigid bodies(zero applies no force to cloth, 1 applies the same) */
var(Cloth) const float ClothForceScale;
/** Amount to scale impulses applied to cloth simulation. */
var(Cloth) float ClothImpulseScale;
/**
The cloth tear factor for this SkeletalMeshComponent, negative values take the tear factor from the SkeletalMesh.
Note: UpdateClothParams() should be called after modification so that the changes are reflected in the simulation.
*/
var(Cloth) const float ClothAttachmentTearFactor;
/** If TRUE, soft body uses compartment in physics scene (usually with fixed timstep for better behaviour) */
var(Cloth) const bool bClothUseCompartment;
/** If TRUE, cloth will collide with scene shapes */
var(Cloth) const bool bClothUseSceneCollision;
/** If the distance traveled between frames exceeds this value the vertices will be reset to avoid stretching. */
var(Cloth) const float MinDistanceForClothReset;
/** Last location of our owner/base for checking MinDistanceForClothReset. */
var const transient vector LastClothLocation;
/** Enum indicating what type of object this apex clothing should be considered for rigid body collision. */
var(ApexClothing) const ERBCollisionChannel ApexClothingRBChannel;
/** Types of objects that this clothing will collide with. */
var(ApexClothing) const RBCollisionChannelContainer ApexClothingRBCollideWithChannels;
/** Enum indicating what channel the apex clothing collision shapes should be placed in */
var(ApexClothing) const ERBCollisionChannel ApexClothingCollisionRBChannel;
/** If true, the clothing actor will stop simulating when it is not rendered */
var(ApexClothing) bool bAutoFreezeApexClothingWhenNotRendered;
/** If TRUE, WindVelocity is applied in the local space of the component, rather than world space. */
var(ApexClothing) bool bLocalSpaceWind;
/** The Wind Velocity applied to Apex Clothing */
var(ApexClothing) interp vector WindVelocity;
/** Time taken for ApexClothing to reach WindVelocity */
var(ApexClothing) interp float WindVelocityBlendTime;
// NVCHANGE_BEGIN: hlanker - Add wind noise
/** Maximum noise amplitude */
var(ApexClothing) float WindStrengthNoiseBounds;
/** Maximum wind strength change per second */
var(ApexClothing) float WindStrengthNoiseStepSize;
/** Higher probability to stay around the center */
var(ApexClothing) bool bWindStrengthNoiseCentered;
/** Maximum angle (in radian) on direction noise*/
var(ApexClothing) float WindDirNoiseBounds;
/** Maximum angle change (in radian per second) */
var(ApexClothing) float WindDirNoiseStepSize;
/** Higher probability to stay around the center */
var(ApexClothing) bool bWindDirNoiseCentered;
/** State of the wind noise */
var transient float WindCurrentStrengthNoise;
var transient vector WindCurrentDirNoise;
// NVCHANGE_END: hlanker - Add wind noise
/** Don't attempt to initialize clothing when component is attached */
var const transient bool bSkipInitClothing;
/** Pointer to the simulated NxSoftBody object. */
var const native transient pointer SoftBodySim;
/** Index of the Novodex scene the soft-body resides in. */
var const native transient int SoftBodySceneIndex;
/** Whether soft-body simulation should currently be used on this SkeletalMeshComponent. */
var(Softbody) const bool bEnableSoftBodySimulation;
/** Buffer of the updated tetrahedron-vertex positions. */
var const array<vector> SoftBodyTetraPosData;
/** Buffer of the updated tetrahedron-indices. */
var const array<int> SoftBodyTetraIndexData;
/** Number of tetrahedron vertices of the soft-body mesh. */
var int NumSoftBodyTetraVerts;
/** Number of tetrahedron indices of the soft-body mesh (equal to four times the number of tetrahedra). */
var int NumSoftBodyTetraIndices;
/** Amount to scale impulses applied to soft body simulation. */
var(SoftBody) float SoftBodyImpulseScale;
/** If true, the soft-body is 'frozen' and no simulation is taking place for it, though it will keep its shape. */
var(SoftBody) const bool bSoftBodyFrozen;
/** If true, the soft-body will automatically have bSoftBodyFrozen set when it is not rendered, and have it turned off when it is seen. */
var(SoftBody) bool bAutoFreezeSoftBodyWhenNotRendered;
/** If true, the soft-body will be awake when a level is started, otherwise it will be instantly put to sleep. */
var(SoftBody) bool bSoftBodyAwakeOnStartup;
/** If TRUE, soft body uses compartment in physics scene (usually with fixed timstep for better behaviour) */
var(SoftBody) const bool bSoftBodyUseCompartment;
/** Enum indicating what type of object this soft-body should be considered for rigid body collision. */
var(SoftBody) const ERBCollisionChannel SoftBodyRBChannel;
/** Types of objects that this soft-body will collide with. */
var(SoftBody) const RBCollisionChannelContainer SoftBodyRBCollideWithChannels;
/** Pointer to the Novodex plane-actor used when previewing the soft-body in the AnimSet Editor. */
var const native transient pointer SoftBodyASVPlane;
var material LimitMaterial;
/** Root Motion extracted from animation. */
var transient BoneAtom RootMotionDelta;
/** Root Motion velocity for this frame, set from RootMotionDelta. */
var transient Vector RootMotionVelocity;
/**
* Offset of the root bone from the reference pose.
* Used to offset bounding box.
*/
var const transient Vector RootBoneTranslation;
/** Scale applied in physics when RootMotionMode == RMM_Accel */
var vector RootMotionAccelScale;
enum ERootMotionMode
{
RMM_Translate, // move actor with root motion
RMM_Velocity, // extract magnitude from root motion, and limit max Actor velocity with it.
RMM_Ignore, // do nothing
RMM_Accel, // extract velocity from root motion and use it to derive acceleration of the Actor
RMM_Relative, // if bHardAttach is used, then affect relative location instead of location.
};
var() ERootMotionMode RootMotionMode;
/** Previous Root Motion Mode, to catch changes */
var const ERootMotionMode PreviousRMM;
var ERootMotionMode PendingRMM;
var ERootMotionMode OldPendingRMM;
/** Handle one frame delay with PendingRMM */
var const INT bRMMOneFrameDelay;
/** Root Motion Rotation mode */
enum ERootMotionRotationMode
{
/** Ignore rotation delta passed from animation. */
RMRM_Ignore,
/** Apply rotation delta to actor */
RMRM_RotateActor,
};
var() ERootMotionRotationMode RootMotionRotationMode;
enum EAnimRotationOnly
{
/** Use settings defined in each AnimSet (default) */
EARO_AnimSet,
/** Force AnimRotationOnly enabled on all AnimSets, but for this SkeletalMesh only */
EARO_ForceEnabled,
/** Force AnimRotationOnly disabled on all AnimSets, but for this SkeletalMesh only */
EARO_ForceDisabled
};
/** SkeletalMeshComponent settings for AnimRotationOnly */
var() EAnimRotationOnly AnimRotationOnly;
enum EFaceFXBlendMode
{
/**
* Face FX overwrites relevant bones on skeletal mesh.
* Default.
*/
FXBM_Overwrite,
/**
* Face FX transforms are relative to ref skeleton and added
* in parent bone space.
*/
FXBM_Additive,
};
/** How FaceFX transforms should be blended with skeletal mesh */
var() EFaceFXBlendMode FaceFXBlendMode;
/** The valid FaceFX register operations. */
enum EFaceFXRegOp
{
FXRO_Add, // Add the register value with the Face Graph node value.
FXRO_Multiply, // Multiply the register value with the Face Graph node value.
FXRO_Replace, // Replace the Face Graph node value with the register value.
};
/** The valid BoneVisibilityStates values; A bone is only visible if it is *exactly* 1 */
enum EBoneVisibilityStatus
{
BVS_HiddenByParent, // Bone is hidden because it's parent is hidden
BVS_Visible, // Bone is visible
BVS_ExplicitlyHidden, // Bone is hidden directly
};
/** The FaceFX actor instance associated with the skeletal mesh component. */
var transient native pointer FaceFXActorInstance;
/**
* The audio component that we are using to play audio for a facial animation.
* Assigned in PlayFaceFXAnim and cleared in StopFaceFXAnim.
*/
var AudioComponent CachedFaceFXAudioComp;
/** Array of bone visibilities (containing one of the values in EBoneVisibilityStatus for each bone). A bone is only visible if it is *exactly* 1 (BVS_Visible) */
var transient const array<byte> BoneVisibilityStates;
// WWISEMODIF_START
/**
* The audio AkEvent that we are using to play audio for a facial animation.
* Assigned in PlayFaceFXAnim and cleared in StopFaceFXAnim.
*/
var AkEvent CachedFaceFxAkEvent;
// WWISEMODIF_END
/** Cache of LocalToWorld BoneAtom. */
var transient const boneatom LocalToWorldBoneAtom;
/** Editor only. Used for visualizing drawing order in Animset Viewer. If < 1.0,
* only the specified fraction of triangles will be rendered
*/
var transient float ProgressiveDrawingFraction;
/** Editor only. Used for manually selecting the alternate indices for
* TRISORT_CustomLeftRight sections.
*/
var transient byte CustomSortAlternateIndexMode;
/** Editor only. Used to keep track of the morph targets we've reported
* the user as having bad LODs (to prevent LOD spam)
*/
var transient array<Name> MorphTargetsQueried;
`if(`__TW_)
/** If set, the LOD for this component will be change in lockstep with the LODParent */
var SkeletalMeshComponent LODParent;
/** Whether the primitive supports cheap on/off environment preshadows from the dominant directional light */
var(Lighting) bool bAllowBooleanPreshadows;
/** If the component is using boolean preshadows, then this determines "how much" it is shadowed */
var transient float InterpolatedBooleanPreshadowFactor;
/** Tracks the latest boolean shadow factor and from last time it was updated for interpolation purposes */
var transient float CurrentBooleanPreshadowFactor;
var transient float LastBooleanPreshadowFactor;
/** Tracks when the boolean shadows were last updated */
var transient double LastBooleanPreshadowUpdateTime;
`endif
/** PhysicsBody options when bone is hiddne */
enum EPhysBodyOp
{
PBO_None, // don't do anything
PBO_Term, // terminate - if you terminate, you won't be able to re-init when unhidden
PBO_Disable, // disable collision - it will enable collision when unhidden
};
/*-----------------------------------------------------------------------------
Tick time optimization.
-----------------------------------------------------------------------------*/
/** Whether to use based on distance factor tick optimization. */
var(Optimization) const bool bUseTickOptimization;
/** How many times this component was ticked. */
var const int TickCount;
/** Last drop rate [0-2]. */
var transient const int LastDropRate;
/** Time when LastDropRate changes, used to avoid 'flickering' when drop rates changes very frequently. */
var transient const float LastDropRateChange;
/** Accumulated delta time when frames were dropped. */
var transient const float AccumulatedDroppedDeltaTime;
/** Accumulated delta time when frames were dropped. */
var transient const float ComponentDroppedDeltaTime;
//=============================================================================
// Animation.
// Attachment functions.
native final function AttachComponent(ActorComponent Component,name BoneName,optional vector RelativeLocation,optional rotator RelativeRotation,optional vector RelativeScale);
native final function DetachComponent(ActorComponent Component);
/**
* Attach an ActorComponent to a Socket.
*/
native final function AttachComponentToSocket(ActorComponent Component, name SocketName);
/**
* Find the current world space location and rotation of a named socket on the skeletal mesh component.
* If the socket is not found, then it returns false and does not change the OutLocation/OutRotation variables.
* @param InSocketName the name of the socket to find
* @param OutLocation (out) set to the world space location of the socket
* @param OutRotation (out) if specified, set to the world space rotation of the socket
* @return whether or not the socket was found
*/
native final function bool GetSocketWorldLocationAndRotation(name InSocketName, out vector OutLocation, optional out rotator OutRotation, optional int Space ); // 0 == World, 1 == Local (Component)
`if(`__TW_)
/** @return the world space matrix of the socket with the specified name */
native final function matrix GetSocketMatrix( name SocketName );
`endif
/**
* Returns SkeletalMeshSocket of named socket on the skeletal mesh component.
* Returns None if not found.
*/
native final function SkeletalMeshSocket GetSocketByName( Name InSocketName );
/**
* Returns bone name linked to a given named socket on the skeletal mesh component.
* If you're unsure to deal with sockets or bones names, you can use this function to filter through, and always return the bone name.
* @input bone name or socket name
* @output bone name
*/
native final function Name GetSocketBoneName(Name InSocketName);
/**
* Returns component attached to specified BoneName. (returns the first entry found).
* @param BoneName Bone Name to look up.
* @return First ActorComponent found, attached to BoneName, if it exists.
*/
native final function ActorComponent FindComponentAttachedToBone( name InBoneName );
/**
* Returns true if component is attached to skeletal mesh.
* @param Component ActorComponent to check for.
* @return true if Component is attached to SkeletalMesh.
*/
native final function bool IsComponentAttached( ActorComponent Component, optional Name BoneName );
/** returns all attached components that are of the specified class or a subclass
* @param BaseClass the base class of ActorComponent to return
* @param (out) OutComponent the returned ActorComponent for each iteration
*/
native final iterator function AttachedComponents(class<ActorComponent> BaseClass, out ActorComponent OutComponent);
/**
* Return Transform Matrix for SkeletalMeshComponent considering root motion setups
*
* @param SkelComp SkeletalMeshComponent to get transform matrix from
*/
native final function Matrix GetTransformMatrix();
// Skeletal animation.
/** Change the SkeletalMesh that is rendered for this Component. Will re-initialize the animation tree etc. */
simulated native final function SetSkeletalMesh(SkeletalMesh NewMesh, optional bool bKeepSpaceBases);
/** Change the Physics Asset of the mesh */
// NVCHANGE_BEGIN: JCAO - Add the seperated PhysicsAsset for flex
simulated native final function SetPhysicsAsset(PhysicsAsset NewPhysicsAsset, optional PhysicsAsset NewPhysicsAssetForFlex, optional bool bForceReInit);
// NVCHANGE_END: JCAO - Add the seperated PhysicsAsset for flex
/** Change whether to force mesh into ref pose (and use cheaper vertex shader) */
simulated native final function SetForceRefPose(bool bNewForceRefPose);
// Cloth
/** Turn on and off cloth simulation for this skeletal mesh. */
simulated native final function SetEnableClothSimulation(bool bInEnable);
/** Toggle active simulation of cloth. Cheaper than doing SetEnableClothSimulation, and keeps its shape while frozen. */
simulated native final function SetClothFrozen(bool bNewFrozen);
/** Toggle active simulation of clothing and keeps its shape while frozen. */
simulated native final function SetEnableClothingSimulation(bool bInEnable);
/** Update params of the this components internal cloth sim from the SkeletalMesh properties. */
simulated native final function UpdateClothParams();
/** Modify the external force that is applied to the cloth. Will continue to be applied until it is changed. */
simulated native final function SetClothExternalForce(vector InForce);
/** Attach/detach verts from physics body that this components actor is attached to. */
simulated native final function SetAttachClothVertsToBaseBody(bool bAttachVerts);
/** Move all vertices in the cloth to the reference pose and zero their velocity. */
simulated native final function ResetClothVertsToRefPose();
/** Forces apex clothing to use 'teleport and reset' for the next update */
simulated native final function ForceApexClothingTeleportAndReset();
/** Forces apex clothing to use 'teleport' for the next update */
simulated native final function ForceApexClothingTeleport();
//Some get*() APIs
simulated native final function float GetClothAttachmentResponseCoefficient();
simulated native final function float GetClothAttachmentTearFactor();
simulated native final function float GetClothBendingStiffness();
simulated native final function float GetClothCollisionResponseCoefficient();
simulated native final function float GetClothDampingCoefficient();
simulated native final function int GetClothFlags();
simulated native final function float GetClothFriction();
simulated native final function float GetClothPressure();
simulated native final function float GetClothSleepLinearVelocity();
simulated native final function int GetClothSolverIterations();
simulated native final function float GetClothStretchingStiffness();
simulated native final function float GetClothTearFactor();
simulated native final function float GetClothThickness();
//some set*() APIs
simulated native final function SetClothAttachmentResponseCoefficient(float ClothAttachmentResponseCoefficient);
simulated native final function SetClothAttachmentTearFactor(float ClothAttachTearFactor);
simulated native final function SetClothBendingStiffness(float ClothBendingStiffness);
simulated native final function SetClothCollisionResponseCoefficient(float ClothCollisionResponseCoefficient);
simulated native final function SetClothDampingCoefficient(float ClothDampingCoefficient);
simulated native final function SetClothFlags(int ClothFlags);
simulated native final function SetClothFriction(float ClothFriction);
simulated native final function SetClothPressure(float ClothPressure);
simulated native final function SetClothSleepLinearVelocity(float ClothSleepLinearVelocity);
simulated native final function SetClothSolverIterations(int ClothSolverIterations);
simulated native final function SetClothStretchingStiffness(float ClothStretchingStiffness);
simulated native final function SetClothTearFactor(float ClothTearFactor);
simulated native final function SetClothThickness(float ClothThickness);
//Other APIs
simulated native final function SetClothSleep(bool IfClothSleep);
simulated native final function SetClothPosition(vector ClothOffSet);
simulated native final function SetClothVelocity(vector VelocityOffSet);
//Attachment API
simulated native final function AttachClothToCollidingShapes(bool AttatchTwoWay, bool AttachTearable);
//ValidBounds APIs
simulated native final function EnableClothValidBounds(bool IfEnableClothValidBounds);
simulated native final function SetClothValidBounds(vector ClothValidBoundsMin, vector ClothValidBoundsMax);
//SoftBody
/** Update soft-body simulation from components params. */
simulated native final function UpdateSoftBodyParams();
/** Toggle active simulation of the soft-body. */
simulated native final function SetSoftBodyFrozen(bool bNewFrozen);
/** Force awake any soft body simulation on this component */
simulated native final function WakeSoftBody();
/**
* Find a named AnimSequence from the AnimSets array in the SkeletalMeshComponent.
* This searches array from end to start, so specific sequence can be replaced by putting a set containing a sequence with the same name later in the array.
*
* @param AnimSeqName Name of AnimSequence to look for.
*
* @return Pointer to found AnimSequence. Returns NULL if could not find sequence with that name.
*/
native final function AnimSequence FindAnimSequence( Name AnimSeqName );
/**
* Saves the skeletal component's current AnimSets to a temporary buffer. You can restore them later by calling
* RestoreSavedAnimSets().
*/
native final function SaveAnimSets();
/**
* Restores saved AnimSets to the master list of AnimSets and clears the temporary saved list of AnimSets.
*/
native final function RestoreSavedAnimSets();
/**
* Finds play Rate for a named AnimSequence to match a specified Duration in seconds.
*
* @param AnimSeqName Name of AnimSequence to look for.
* @param Duration in seconds to match
*
* @return play rate of animation, so it plays in <duration> seconds.
*/
final function float GetAnimRateByDuration( Name AnimSeqName, float Duration )
{
local AnimSequence AnimSeq;
AnimSeq = FindAnimSequence( AnimSeqName );
if( AnimSeq == None || AnimSeq.RateScale <= 0.f )
{
return 1.f;
}
return (AnimSeq.SequenceLength / (Duration * AnimSeq.RateScale));
}
/** Returns the duration (in seconds) for a named AnimSequence. Returns 0.f if no animation. */
final function float GetAnimLength(Name AnimSeqName)
{
local AnimSequence AnimSeq;
AnimSeq = FindAnimSequence(AnimSeqName);
if( AnimSeq == None || AnimSeq.RateScale <= 0.f )
{
return 0.f;
}
return (AnimSeq.SequenceLength / AnimSeq.RateScale);
}
/**
* Find a named MorphTarget from the MorphSets array in the SkeletalMeshComponent.
* This searches the array in the same way as FindAnimSequence
*
* @param AnimSeqName Name of MorphTarget to look for.
*
* @return Pointer to found MorphTarget. Returns NULL if could not find target with that name.
*/
native final function MorphTarget FindMorphTarget( Name MorphTargetName );
/**
* Find an Animation Node in the Animation Tree whose NodeName matches InNodeName.
* Warning: The search is O(n), so for large AnimTrees, cache result.
*/
native final function AnimNode FindAnimNode(name InNodeName);
/** returns all AnimNodes in the animation tree that are the specfied class or a subclass
* @param BaseClass base class to return
* @param Node (out) the returned AnimNode for each iteration
*/
native final iterator function AllAnimNodes(class<AnimNode> BaseClass, out AnimNode Node);
native final function SkelControlBase FindSkelControl( name InControlName );
native final function MorphNodeBase FindMorphNode( name InNodeName );
native final function quat GetBoneQuaternion( name BoneName, optional int Space ); // 0 == World, 1 == Local (Component)
native final function vector GetBoneLocation( name BoneName, optional int Space ); // 0 == World, 1 == Local (Component)
/** returns the bone index of the specified bone, or INDEX_NONE if it couldn't be found */
native final function int MatchRefBone( name BoneName );
/** @return the name of the bone at the specified index */
native final function name GetBoneName(int BoneIndex);
/** returns the matrix of the bone at the specified index */
native final function matrix GetBoneMatrix( int BoneIndex );
/** returns the name of the parent bone for the specified bone. Returns 'None' if the bone does not exist or it is the root bone */
native final function name GetParentBone(name BoneName);
/** fills the given array with the names of all the bones in this component's current SkeletalMesh */
native final function GetBoneNames(out array<name> BoneNames);
/**
* Tests if BoneName is child of (or equal to) ParentBoneName.
* Note - will return FALSE if ChildBoneIndex is the same as ParentBoneIndex ie. must be strictly a child.
*/
native final function bool BoneIsChildOf(name BoneName, name ParentBoneName);
/** Gets the local-space position of a bone in the reference pose. */
native final function vector GetRefPosePosition(int BoneIndex);
/** finds a vector pointing along the given axis of the given bone
* @param BoneName the name of the bone to find
* @param Axis the axis of that bone to return
* @return the direction of the specified axis, or (0,0,0) if the specified bone was not found
*/
native final function vector GetBoneAxis(name BoneName, EAxis Axis);
/**
* Transform a location/rotation from world space to bone relative space.
* This is handy if you know the location in world space for a bone attachment, as AttachComponent takes location/rotation in bone-relative space.
*/
native final function TransformToBoneSpace( name BoneName, vector InPosition, rotator InRotation, out vector OutPosition, out rotator OutRotation );
/**
* Transform a location/rotation in bone relative space to world space.
*/
native final function TransformFromBoneSpace( name BoneName, vector InPosition, rotator InRotation, out vector OutPosition, out rotator OutRotation );
/** finds the closest bone to the given location
* @param TestLocation the location to test against
* @param BoneLocation (optional, out) if specified, set to the world space location of the bone that was found, or (0,0,0) if no bone was found
* @param IgnoreScale (optional) if specified, only bones with scaling larger than the specified factor are considered
* @return the name of the bone that was found, or 'None' if no bone was found
*/
native final function name FindClosestBone(vector TestLocation, optional out vector BoneLocation, optional float IgnoreScale);
`if(`__TW_)
/** finds n closest bones to the given location
* @param TestLocation the location to test against (world space)
* @param NumBones Number of bones to return in the ClosestBonesList
* @param ClosestBonesList Contains the names of the closest bones to the TestLocation
* @param SearchBonesList (optional) Restrict the search to the these bones only. If not specified, search the entire bone hierarchy
* @param IgnoreScale (optional) if specified, only bones with scaling larger than the specified factor are considered
* @return True if succeeded, False if no valid bone was found
*/
native final function bool FindClosestBones(vector TestLocation, int NumBones, out array<name> ClosestBonesList, optional array<name> SearchBonesList, optional float IgnoreScale);
`endif
/** iterates through all bodies in our PhysicsAsset and returns the location of the closest bone associated
* with a body that blocks the specified kind of traces
* @note: only the collision flags on the PhysicsAsset are checked; the collision flags on the component are ignored
* @param TestLocation - location to check against
* @param bCheckZeroExtent - consider bodies that block zero extent traces
* @param bCheckNonZeroExtent - consider bodies that block nonzero extent traces
* @return location of closest colliding bone, or (0,0,0) if there were no bodies to test
*/
native final function vector GetClosestCollidingBoneLocation(vector TestLocation, bool bCheckZeroExtent, bool bCheckNonZeroExtent);
native final function SetAnimTreeTemplate(AnimTree NewTemplate);
native final function SetParentAnimComponent(SkeletalMeshComponent NewParentAnimComp);
native final function UpdateParentBoneMap();
native final function InitSkelControls();
/**
* Initialize MorphSets look up table : MorphTargetIndexMap
*/
native final function InitMorphTargets();
final native function int FindConstraintIndex(name ConstraintName);
final native function name FindConstraintBoneName(int ConstraintIndex);
/** Find a BodyInstance by BoneName */
final native function RB_BodyInstance FindBodyInstanceNamed(Name BoneName);
/**
* Set value of bHasPhysicsAssetInstance flag.
* Will create/destroy PhysicsAssetInstance as desired.
*
* @param bHasInstance - Sets value of flag
* @param bUseCurrentPosition - If true, skip the skeletal update and use current positions
*/
final native function SetHasPhysicsAssetInstance(bool bHasInstance, optional bool bUseCurrentPosition);
/** Force an update of this meshes kinematic bodies and springs. */
native final function UpdateRBBonesFromSpaceBases(bool bMoveUnfixedBodies, bool bTeleport);
/** forces an update to the mesh's skeleton/attachments, even if bUpdateSkelWhenNotRendered is false and it has not been recently rendered
* @note if bUpdateSkelWhenNotRendered is true, there is no reason to call this function (but doing so anyway will have no effect)
*/
native final function ForceSkelUpdate();
/**
* Force AnimTree to recache all animations.
* Call this when the AnimSets array has been changed.
*/
native final function UpdateAnimations();
/**
* Find all bones by name within given radius
*/
native final function bool GetBonesWithinRadius( Vector Origin, FLOAT Radius, INT TraceFlags, out array< Name > out_Bones );
/**
* Add a new bone to the list of instance vertex weight bones
*
* @param BoneNames - set of bones (implicitly parented) to use for finding vertices
*/
native final function AddInstanceVertexWeightBoneParented(name BoneName, optional bool bPairWithParent = TRUE);
/**
* Remove a new bone to the list of instance vertex weight bones
*
* @param BoneNames - set of bones (implicitly parented) to use for finding vertices
*/
native final function RemoveInstanceVertexWeightBoneParented(name BoneName);
/**
* Find an existing bone pair entry in the list of InstanceVertexWeightBones
*
* @param Bones - pair of bones to search for
* @return index of entry found or -1 if not found
*/
native final function int FindInstanceVertexweightBonePair(BonePair Bones);
/**
* Update the bones that specify which vertices will use instanced influences
* This will also trigger an update of the vertex weights.
*
* @param BonePairs - set of bone pairs to use for finding vertices.
* A bone can be paired with None bone name to only match up a single bone.
*/
native final function UpdateInstanceVertexWeightBones(array<BonePair> BonePairs);
/**
* Enabled or disable the instanced vertex weights buffer for the skeletal mesh object
*
* @param bEnable - TRUE to enable, FALSE to disable
* @param LODIdx - LOD to enable
*/
native final function ToggleInstanceVertexWeights(bool bEnable, INT LODIdx);
// FaceFX.
/**
* Play the specified FaceFX animation.
* Returns TRUE if successful.
* If animation couldn't be found, a log warning will be issued.
*/
// WWISEMODIF_START, alessard, nov-28-2008, WwiseAudioIntegration
native final function bool PlayFaceFXAnim(FaceFXAnimSet FaceFXAnimSetRef, string AnimName, string GroupName, SoundCue SoundCueToPlay, AkEvent AkEventToPlay);
// WWISEMODIF_END
/** Stop any currently playing FaceFX animation. */
native final function StopFaceFXAnim();
/** Is playing a FaceFX animation. */
native final function bool IsPlayingFaceFXAnim();
/** Declare a new register in the FaceFX register system. This is required
* before using the register name in GetRegister() or SetRegister(). */
native final function DeclareFaceFXRegister( string RegName );
/** Retrieve the value of the specified FaceFX register. */
native final function float GetFaceFXRegister( string RegName );
/** Set the value and operation of the specified FaceFX register. */
native final function SetFaceFXRegister( string RegName, float RegVal, EFaceFXRegOp RegOp, optional float InterpDuration );
/** Set the value and operation of the specified FaceFX register. */
native final function SetFaceFXRegisterEx( string RegName, EFaceFXRegOp RegOp, float FirstValue, float FirstInterpDuration, float NextValue, float NextInterpDuration );
/**
* Hides the specified bone. Currently this just enforces a scale of 0 for the hidden bones.
* @param PhysBodyOption Option for physics bodies that attach to the bones to be hidden
*/
native final function HideBone( int BoneIndex, EPhysBodyOp PhysBodyOption );
/** Unhides the specified bone. */
native final function UnHideBone( int BoneIndex );
/** Determines if the specified bone is hidden. */
native final function bool IsBoneHidden( int BoneIndex );
/**
* Hides the specified bone with name. Currently this just enforces a scale of 0 for the hidden bones.
* Compoared to HideBone By Index - This keeps track of list of bones and update when LOD changes
* @param BoneName Name of bone to hide
* @param PhysBodyOption Option for physics bodies that attach to the bones to be hidden
*/
native final function HideBoneByName( name BoneName, EPhysBodyOp PhysBodyOption );
/**
* UnHide the specified bone with name. Currently this just enforces a scale of 0 for the hidden bones.
* Compoared to HideBone By Index - This keeps track of list of bones and update when LOD changes
* @param BoneName Name of bone to unhide
*/
native final function UnHideBoneByName( name BoneName );
/**
* Looks up all bodies for broken constraints.
* Makes sure child bodies of a broken constraints are not fixed and using bone springs, and child joints not motorized.
*/
simulated final native function UpdateMeshForBrokenConstraints();
/**
* Show/Hide Material - technical correct name for this is Section, but seems Material is mostly used
* This disable rendering of certain Material ID (Section)
*
* @param MaterialID - id of the material to match a section on and to show/hide
* @param bShow - TRUE to show the section, otherwise hide it
* @param LODIndex - index of the lod entry since material mapping is unique to each LOD
*/
simulated final native function ShowMaterialSection(int MaterialID, bool bShow, int LODIndex);
/** simple generic case animation player
* requires that the one and only animation node in the AnimTree is an AnimNodeSequence
* @param AnimName name of the animation to play
* @param Duration (optional) override duration for the animation
* @param bLoop (optional) whether the animation should loop
* @param bRestartIfAlreadyPlaying whether or not to restart the animation if the specified anim is already playing
* @param StartTime (optional) What time to start the animation at
* @param bPlayBackwards (optional) Play this animation backwards
*/
function bool PlayAnim(name AnimName, optional float Duration, optional bool bLoop, optional bool bRestartIfAlreadyPlaying = true, optional float StartTime=0.0f, optional bool bPlayBackwards=false)
{
local AnimNodeSequence AnimNode;
local float DesiredRate;
local bool bIsAnimPlayed;
bIsAnimPlayed = false;
AnimNode = AnimNodeSequence(Animations);
if (AnimNode == None && Animations.IsA('AnimTree'))
{
AnimNode = AnimNodeSequence(AnimTree(Animations).Children[0].Anim);
}
if (AnimNode == None)
{
`warn("Base animation node is not an AnimNodeSequence (Owner:" @ Owner $ ")");
}
else
{
if (AnimNode.AnimSeq != None && AnimNode.AnimSeq.SequenceName == AnimName)
{
DesiredRate = (Duration > 0.0) ? (AnimNode.AnimSeq.SequenceLength / (Duration * AnimNode.AnimSeq.RateScale)) : 1.0;
DesiredRate = (bPlayBackwards) ? -DesiredRate : DesiredRate;
if (bRestartIfAlreadyPlaying || !AnimNode.bPlaying)
{
AnimNode.PlayAnim(bLoop, DesiredRate, StartTime);
bIsAnimPlayed = true;
}
else
{
AnimNode.Rate = DesiredRate;
AnimNode.bLooping = bLoop;
}
}
else
{
AnimNode.SetAnim(AnimName);
if (AnimNode.AnimSeq != None)
{
DesiredRate = (Duration > 0.0) ? (AnimNode.AnimSeq.SequenceLength / (Duration * AnimNode.AnimSeq.RateScale)) : 1.0;
DesiredRate = (bPlayBackwards) ? -DesiredRate : DesiredRate;
AnimNode.PlayAnim(bLoop, DesiredRate, StartTime);
bIsAnimPlayed = true;
}
}
}
return bIsAnimPlayed;
}
/** simple generic case animation stopper
* requires that the one and only animation node in the AnimTree is an AnimNodeSequence
*/
function StopAnim()
{
local AnimNodeSequence AnimNode;
AnimNode = AnimNodeSequence(Animations);
if (AnimNode == None && Animations.IsA('AnimTree'))
{
AnimNode = AnimNodeSequence(AnimTree(Animations).Children[0].Anim);
}
if (AnimNode == None)
{
`warn("Base animation node is not an AnimNodeSequence (Owner:" @ Owner $ ")");
}
else
{
AnimNode.StopAnim();
}
}
/**
* Called by AnimNotify_ForceField
* Looks for a socket name first then bone name
*
* @param AnimNotifyData The AnimNotify_ForceField which will have all of the various params on it
*
* @return bool true if the forcefield was created, false if not;
*/
event bool CreateForceField( const AnimNotify_Forcefield AnimNotifyData )
{
local NxForceFieldComponent NewForceFieldComponent;
NewForceFieldComponent =
new(self) AnimNotifyData.ForceFieldComponent.Class(AnimNotifyData.ForceFieldComponent);
NewForceFieldComponent.DoInitRBPhys();
if( AnimNotifyData.SocketName != '' )
{
AttachComponentToSocket( NewForceFieldComponent, AnimNotifyData.SocketName );
}
else if( AnimNotifyData.BoneName != '' )
{
AttachComponent( NewForceFieldComponent, AnimNotifyData.BoneName );
}
return true;
}
/**
* Called by AnimNotify_PlayParticleEffect
* Looks for a socket name first then bone name
*
* @param AnimNotifyData The AnimNotify_PlayParticleEffect which will have all of the various params on it
*/
event bool PlayParticleEffect( const AnimNotify_PlayParticleEffect AnimNotifyData )
{
local vector Loc;
local rotator Rot;
local WorldInfo WI;
local ParticleSystemComponent PSC;
local ParticleSystemComponent EmitterPSC;
local bool bPlayNonExtreme;
WI = class'WorldInfo'.static.GetWorldInfo();
if (WI.NetMode == NM_DedicatedServer)
{
`Log("(SkeletalMeshComponent): PlayParticleEffect on dedicated server!");
return true;
}
if (AnimNotifyData.PSTemplate == none)
{
return false;
}
// should I play non extreme content?
bPlayNonExtreme = ( AnimNotifyData.bIsExtremeContent && class'Engine'.static.IsGame() && !WI.GRI.ShouldShowGore() ) ;
// if we should not respond to anim notifies OR if this is extreme content and we can't show extreme content then return
if ( bPlayNonExtreme && AnimNotifyData.PSNonExtremeContentTemplate==None )
{
return false;
}
// now go ahead and spawn the particle system based on whether we need to attach it or not
if (AnimNotifyData.bAttach)
{
PSC = new(self) class'ParticleSystemComponent'; // move this to the object pool once it can support attached to bone/socket and relative translation/rotation
if ( bPlayNonExtreme )
{
PSC.SetTemplate( AnimNotifyData.PSNonExtremeContentTemplate );
}
else
{
PSC.SetTemplate( AnimNotifyData.PSTemplate );
}
if( AnimNotifyData.SocketName != '' )
{
//`log( "attaching AnimNotifyData.SocketName" );
AttachComponentToSocket( PSC, AnimNotifyData.SocketName );
}
else if( AnimNotifyData.BoneName != '' )
{
//`log( "attaching AnimNotifyData.BoneName" );
AttachComponent( PSC, AnimNotifyData.BoneName );
}
PSC.ActivateSystem(true);
PSC.OnSystemFinished = SkelMeshCompOnParticleSystemFinished;
}
else
{
// find the location
if( AnimNotifyData.SocketName != '' )
{
GetSocketWorldLocationAndRotation( AnimNotifyData.SocketName, Loc, Rot );
}
else if( AnimNotifyData.BoneName != '' )
{
Loc = GetBoneLocation( AnimNotifyData.BoneName );
Rot = rot(0,0,1);
}
else
{
Loc = GetPosition();
Rot = rot(0,0,1);
}
if (Owner != None && Owner.WorldInfo != None && Owner.WorldInfo.MyEmitterPool != None)
{
if ( bPlayNonExtreme )
{
EmitterPSC = Owner.WorldInfo.MyEmitterPool.SpawnEmitter( AnimNotifyData.PSNonExtremeContentTemplate, Loc, Rot );
}
else
{
EmitterPSC = Owner.WorldInfo.MyEmitterPool.SpawnEmitter( AnimNotifyData.PSTemplate, Loc, Rot );
}
}
else
{
if (class'Engine'.static.IsGame())
{
PSC = new(self) class'ParticleSystemComponent'; // move this to the object pool once it can support attached to bone/socket and relative translation/rotation
PSC.SetTemplate( AnimNotifyData.PSTemplate );
PSC.SetAbsolute(true, true, true);
PSC.SetTranslation( Loc );
PSC.SetRotation( Rot );
PSC.ActivateSystem(true);
PSC.OnSystemFinished = SkelMeshCompOnParticleSystemFinished;
}
else if (class'Engine'.static.IsEditor())
{
PSC = new(self) class'ParticleSystemComponent'; // move this to the object pool once it can support attached to bone/socket and relative translation/rotation
PSC.SetTemplate( AnimNotifyData.PSTemplate );
PSC.SetAbsolute(true, true, true);
PSC.SetTranslation( Loc );
PSC.SetRotation( Rot );
if( AnimNotifyData.SocketName != '' )
{
//`log( "attaching AnimNotifyData.SocketName" );
AttachComponentToSocket( PSC, AnimNotifyData.SocketName );
}
else if( AnimNotifyData.BoneName != '' )
{
//`log( "attaching AnimNotifyData.BoneName" );
AttachComponent( PSC, AnimNotifyData.BoneName );
}
PSC.ActivateSystem(true);
PSC.OnSystemFinished = SkelMeshCompOnParticleSystemFinished;
}
else
{
// It should *never* get in here... but just in case
return false;
}
}
}
if( PSC != None && AnimNotifyData.BoneSocketModuleActorName != '' && Owner != None )
{
// NVCHANGE_BEGIN: JCAO - Apply the lightingChannel for the particle from the pawn
PSC.SetLightingChannels(LightingChannels);
// NVCHANGE_END: JCAO - Apply the lightingChannel for the particle from the pawn
PSC.SetActorParameter(AnimNotifyData.BoneSocketModuleActorName, Owner);
}
`if(`__TW_)
// We use this to keep track of particle systems spawned by animations
if( PSC != none && Owner != none )
{
Owner.OnAnimNotifyParticleSystemSpawned( AnimNotifyData, PSC );
}
if (EmitterPSC != none && Owner != none)
{
Owner.OnAnimNotifyParticleSystemSpawned(AnimNotifyData, EmitterPSC);
}
`endif
return true;
}
/** We so we detach the Component once we are done playing it **/
simulated function SkelMeshCompOnParticleSystemFinished( ParticleSystemComponent PSC )
{
DetachComponent( PSC );
}
`if(`__TW_)
/** Toggles to alternate bone weights without breaking constraints */
simulated final function ToggleAlternateBoneWeights(Name InBoneName)
{
local int LODIdx;
// you can enable/disable the instanced weights by calling
for (LODIdx=0; LODIdx<LODInfo.length;LODIdx++)
{
if (LODInfo[LODIdx].InstanceWeightUsage == IWU_PartialSwap)
{
ToggleInstanceVertexWeights( TRUE, LODIdx );
}
}
AddInstanceVertexWeightBoneParented( InBoneName );
}
`endif
/** Break a constraint off a Gore mesh. */
`if(`__TW_)
// SRS - Handle applying impulse separately
simulated final function BreakConstraint(Name InBoneName)
`else
simulated final function BreakConstraint(Vector Impulse, Vector HitLocation, Name InBoneName, optional bool bVelChange)
`endif
{
local int ConstraintIndex, LODIdx;
local RB_ConstraintInstance Constraint;
local RB_ConstraintSetup ConstraintSetup;
local RB_BodyInstance Body;
`if(`__TW_)
local int BodyIndex;
`endif
// you can enable/disable the instanced weights by calling
ConstraintIndex = FindConstraintIndex(InBoneName);
if( ConstraintIndex == INDEX_NONE )
{
return;
}
Constraint = PhysicsAssetInstance.Constraints[ConstraintIndex];
// If already broken, our job has already been done. Bail!
if( Constraint.bTerminated )
{
return;
}
// you can enable/disable the instanced weights by calling
for (LODIdx=0; LODIdx<LODInfo.length;LODIdx++)
{
if (LODInfo[LODIdx].InstanceWeightUsage == IWU_PartialSwap)
{
ToggleInstanceVertexWeights( TRUE, LODIdx );
}
}
AddInstanceVertexWeightBoneParented( InBoneName );
// Figure out if Body is fixed or not
ConstraintSetup = PhysicsAsset.ConstraintSetup[Constraint.ConstraintIndex];
Body = FindBodyInstanceNamed(ConstraintSetup.JointName);
if( Body != None && Body.IsFixed() )
{
// Unfix body so it can be broken.
Body.SetFixed(FALSE);
}
// Break Constraint
Constraint.TermConstraint();
// Make sure child bodies and constraints are released and turned to physics.
UpdateMeshForBrokenConstraints();
`if(`__TW_)
// If the constraint being broken is considered for bounds but has no collision,
// shrink it so that the mesh doesn't fall out of the world
BodyIndex = PhysicsAsset.FindBodyIndex(InBoneName);
if( BodyIndex != INDEX_None )
{
if( PhysicsAsset.BodySetup[BodyIndex].bConsiderForBounds && PhysicsAsset.BodySetup[BodyIndex].bNoCollision )
{
HideBoneByName(InBoneName, PBO_None);
}
}
// Do not handle any impulse calculations here.
`else
// Add impulse to broken limb
AddImpulse(Impulse, HitLocation, InBoneName, bVelChange);
`endif
}
`if(`__TW_)
/** @return whether the constraint specified by the bone name is already broken or not */
simulated final function bool IsBrokenConstraint(name InBoneName)
{
local int ConstraintIndex;
local RB_ConstraintInstance Constraint;
ConstraintIndex = FindConstraintIndex(InBoneName);
if( ConstraintIndex == INDEX_NONE )
{
return false;
}
Constraint = PhysicsAssetInstance.Constraints[ConstraintIndex];
return Constraint.bTerminated;
}
`endif
/** Returns position of the component, in world space. */
native function vector GetPosition();
/** Returns rotation of the component, in world space. */
native function rotator GetRotation();
native virtual function SetMaterial(int ElementIndex, MaterialInterface Material);
`if(`__TW_)
/**
* Changes the value of LODParent.
* @param NewLODParent - The value to assign to LODParent.
*/
native final function SetLODParent(SkeletalMeshComponent NewLODParent);
`endif
defaultproperties
{
GlobalAnimRateScale=1.0
// Various physics related items need to be ticked pre physics update
TickGroup=TG_PreAsyncWork
RootMotionMode=RMM_Ignore
PreviousRMM=RMM_Ignore
RootMotionRotationMode=RMRM_Ignore
FaceFXBlendMode=FXBM_Additive
AnimRotationOnly=EARO_AnimSet
ChunkIndexPreview=-1
SectionIndexPreview=-1
`if(`__TW_)
// Resort to color that was hardcoded in native (previously)
WireframeColor=(R=221,G=255,B=255,A=255)
`else
WireframeColor=(R=221,G=221,B=28,A=255)
`endif
bTransformFromAnimParent=1
// by default, update kinematic when the mesh is far in the distance as things falling out of the world and are hard to track down
MinDistFactorForKinematicUpdate=0.0f
bNoSkeletonUpdate=FALSE
bUpdateSkelWhenNotRendered=TRUE
bTickAnimNodesWhenNotRendered=TRUE
bAutoFreezeClothWhenNotRendered=TRUE
bUpdateKinematicBonesFromAnimation=TRUE
bSyncActorLocationToRootRigidBody=TRUE
TickCount=0
bUseTickOptimization=TRUE
// re-rendering mesh for each decal is slow, and sometimes can't even be seen
bAcceptsStaticDecals=FALSE
bAcceptsDynamicDecals=FALSE
RootMotionAccelScale=(X=1.f,Y=1.f,Z=1.f)
StreamingDistanceMultiplier=1.0
bClothUseCompartment=FALSE
bClothAwakeOnStartup=FALSE
ClothRBChannel=RBCC_Cloth
ClothBlendWeight=1.0
ClothImpulseScale=1.0
ClothBlendMinDistanceFactor=-1.0
ClothAttachmentTearFactor=-1.0
MinDistanceForClothReset=256.f
ApexClothingRBChannel=RBCC_Clothing
ApexClothingCollisionRBChannel=RBCC_ClothingCollision
ApexClothingRBCollideWithChannels=(Default=TRUE,BlockingVolume=TRUE,GameplayPhysics=TRUE,EffectPhysics=TRUE,ClothingCollision=TRUE)
bAutoFreezeApexClothingWhenNotRendered=TRUE
bSoftBodyAwakeOnStartup=FALSE
SoftBodyRBChannel=RBCC_SoftBody
SoftBodyImpulseScale=1.0
bSoftBodyUseCompartment=TRUE
bCacheAnimSequenceNodes=TRUE
LineCheckBoundsScale=(X=1,Y=1,Z=1)
ProgressiveDrawingFraction=1.0
bCanHighlightSelectedSections=false;
AnimationLODFrameRate=2
//@zombie_ps4_begin
LowUpdateFrameRate=2
//@zombie_ps4_end
//debug
//bDisplayBones=1
// NVCHANGE: Lou - Fix cloth wind (use APEX method, add adaption)
ClothWindBlendTime=5
`if(`__TW_LIGHTING_MODIFICATIONS_)
bAllowBooleanPreshadows=true
InterpolatedBooleanPreshadowFactor=-1.f //disabled
`endif
}