1864 lines
73 KiB
Ucode
1864 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 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;
|
|
|
|
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);
|
|
}
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/** 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
|
|
}
|