Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
Hair.h
Go to the documentation of this file.
1// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2// SPDX-FileCopyrightText: 2026 Jorrit Rouwe
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
12
14
15class PhysicsSystem;
16#ifdef JPH_DEBUG_RENDERER
17class DebugRenderer;
18#endif
19class HairShaders;
20
35{
36public:
38
40 Hair(const HairSettings *inSettings, RVec3Arg inPosition, QuatArg inRotation, ObjectLayer inLayer);
41 ~Hair();
42
44 void Init(ComputeSystem *inComputeSystem);
45
47 void SetPosition(RVec3Arg inPosition) { mPosition = inPosition; }
48 void SetRotation(QuatArg inRotation) { mRotation = inRotation; }
49 RMat44 GetWorldTransform() const { return RMat44::sRotationTranslation(mRotation, mPosition); }
50
52 const HairSettings * GetHairSettings() const { return mSettings; }
53
55 void OnTeleported() { mTeleported = true; }
56
58 void SetScalpVerticesCB(ComputeBuffer *inBuffer) { mScalpVerticesCB = inBuffer; }
59
61 void SetScalpTrianglesCB(ComputeBuffer *inBuffer) { mScalpTrianglesCB = inBuffer; }
62
64 void SetScalpToHead(Mat44Arg inMat) { mScalpToHead = inMat; }
65
67 using RenderPositionsToFloat3 = std::function<void(ComputeBuffer *, Float3 *, uint)>;
68
70 void OverrideRenderPositionsCB(const RenderPositionsToFloat3 &inRenderPositionsToFloat3) { JPH_ASSERT(mRenderPositionsCB == nullptr, "Must be called before Init"); mRenderPositionsOverridden = true; mRenderPositionsToFloat3 = inRenderPositionsToFloat3; }
71
73 void SetRenderPositionsCB(ComputeBuffer *inBuffer) { JPH_ASSERT(mRenderPositionsOverridden, "Must call OverrideRenderPositionsCB first"); mRenderPositionsCB = inBuffer; }
74
83 void Update(float inDeltaTime, Mat44Arg inJointToHair, const Mat44 *inJointMatrices, const PhysicsSystem &inSystem, const HairShaders &inShaders, ComputeSystem *inComputeSystem, ComputeQueue *inComputeQueue);
84
86 ComputeBuffer * GetScalpVerticesCB() const { return mScalpVerticesCB; }
87 ComputeBuffer * GetScalpTrianglesCB() const { return mScalpTrianglesCB; }
88 ComputeBuffer * GetPositionsCB() const { return mPositionsCB; }
89 ComputeBuffer * GetVelocitiesCB() const { return mVelocitiesCB; }
90 ComputeBuffer * GetVelocityAndDensityCB() const { return mVelocityAndDensityCB; }
91 ComputeBuffer * GetRenderPositionsCB() const { return mRenderPositionsCB; }
92
94 void ReadBackGPUState(ComputeQueue *inComputeQueue);
95
97 void LockReadBackBuffers();
98 void UnlockReadBackBuffers();
99
101 const Float3 * GetScalpVertices() const { return mScalpVertices; }
102 const Float3 * GetPositions() const { return mPositions; }
103 const Quat * GetRotations() const { return mRotations; }
104 StridedPtr<const Float3> GetVelocities() const { return { (const Float3 *)&mVelocities->mVelocity, sizeof(JPH_HairVelocity) }; }
105 StridedPtr<const Float3> GetAngularVelocities() const { return { (const Float3 *)&mVelocities->mAngularVelocity, sizeof(JPH_HairVelocity) }; }
106 const Float4 * GetGridVelocityAndDensity() const { return mVelocityAndDensity; }
107 const Float3 * GetRenderPositions() const { return mRenderPositions; }
108
109#ifdef JPH_DEBUG_RENDERER
111 {
112 PerRenderStrand,
113 PerSimulatedStrand,
114 GravityFactor,
115 WorldTransformInfluence,
116 GridVelocityFactor,
117 GlobalPose,
118 SkinGlobalPose,
119 };
120
122 {
124 uint mSimulationStrandBegin = 0;
125 uint mSimulationStrandEnd = UINT_MAX;
126
127 bool mDrawRods = true;
128 bool mDrawUnloadedRods = false;
129 bool mDrawVertexVelocity = false;
130 bool mDrawAngularVelocity = false;
131 bool mDrawOrientations = false;
132 bool mDrawNeutralDensity = false;
133 bool mDrawGridDensity = false;
134 bool mDrawGridVelocity = false;
135 bool mDrawSkinPoints = false;
136 bool mDrawRenderStrands = false;
137 bool mDrawInitialGravity = true;
138 ERenderStrandColor mRenderStrandColor = ERenderStrandColor::PerSimulatedStrand;
139 };
140
142 void Draw(const DrawSettings &inSettings, DebugRenderer *inRenderer);
143#endif // JPH_DEBUG_RENDERER
144
145protected:
148
149 // Information about a colliding shape. Is always a leaf shape, compound shapes are expanded.
151 {
152 LeafShape() = default;
153 LeafShape(Mat44Arg inTransform, Vec3Arg inScale, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity, const Shape *inShape) : mTransform(inTransform), mScale(inScale), mLinearVelocity(inLinearVelocity), mAngularVelocity(inAngularVelocity), mShape(inShape) { }
154
160 };
161
162 // Internal context used during a simulation step
164 {
165 Mat44 mDeltaTransform; // Transforms positions from the old hair transform to the new
166 Quat mDeltaTransformQuat; // Rotation part of mDeltaTransform
167 uint mNumIterations; // Number of iterations to run the solver for
168 bool mNeedsCollision; // If collision detection should be performed
169 bool mNeedsGrid; // If the grid should be calculated
170 bool mGlobalPoseOnly; // If no simulation is needed and only the global pose needs to be applied
171 bool mHasTransformChanged; // If the world transform has changed
172 float mDeltaTime; // Delta time for a sub step
173 float mHalfDeltaTime; // 0.5 * mDeltaTime
174 float mInvDeltaTimeSq; // 1 / mDeltaTime^2
175 float mTwoDivDeltaTime; // 2 / mDeltaTime
176 float mTimeRatio; // Ratio between sub step delta time and default sub step delta time
177 Vec3 mSubStepGravity; // Gravity to apply in a sub step
178 Array<LeafShape> mShapes; // List of colliding shapes
179 };
180
181 // Calculate the UpdateContext parameters
182 void InitializeContext(UpdateContext &outCtx, float inDeltaTime, const PhysicsSystem &inSystem);
183
184 RefConst<HairSettings> mSettings; // Shared hair settings, must be kept alive during the lifetime of this hair instance
185
186 RVec3 mPrevPosition; // Position at the start of the last time step
187 RVec3 mPosition; // Current position in world space
188 Quat mPrevRotation; // Rotation at the start of the last time step
189 Quat mRotation; // Current rotation in world space
190 bool mTeleported = true; // If the hair got teleported and should be set to the default pose
191 ObjectLayer mLayer; // Layer for the hair to collide with
192
193 Mat44 mScalpToHead = Mat44::sIdentity(); // When skipping skinning, this allow specifying a transform that transforms the scalp mesh into head space
194
195 bool mRenderPositionsOverridden = false; // Indicates that the render positions buffer is provided externally
196 RenderPositionsToFloat3 mRenderPositionsToFloat3; // Function that transforms the render positions buffer to Float3 vertices for debugging purposes
197
201 Ref<ComputeBuffer> mTargetPositionsCB; // Target root positions determined by skinning (where we're interpolating to, eventually written to mPositionsCB)
202 Ref<ComputeBuffer> mTargetGlobalPoseTransformsCB; // Target global pose transforms determined by skinning (where we're interpolating to, eventually written to mGlobalPoseTransformsCB)
203 Ref<ComputeBuffer> mGlobalPoseTransformsCB; // Current global pose transforms used for skinning the hairs
217
218 // Only valid after ReadBackGPUState has been called
224 const Float3 * mScalpVertices = nullptr;
225 Float3 * mPositions = nullptr;
226 Quat * mRotations = nullptr;
227 JPH_HairVelocity * mVelocities = nullptr;
228 const Float4 * mVelocityAndDensity = nullptr;
229 const Float3 * mRenderPositions = nullptr;
230};
231
#define JPH_EXPORT
Definition Core.h:303
unsigned int uint
Definition Core.h:564
#define JPH_NAMESPACE_END
Definition Core.h:487
#define JPH_NAMESPACE_BEGIN
Definition Core.h:481
#define JPH_ASSERT(...)
Definition IssueReporting.h:28
#define JPH_OVERRIDE_NEW_DELETE
Macro to override the new and delete functions.
Definition Memory.h:51
uint16 ObjectLayer
Layer that objects can be in, determines which other objects it can collide with.
Definition ObjectLayer.h:13
Definition Array.h:22
Buffer that can be read from / written to by a compute shader.
Definition ComputeBuffer.h:18
Definition ComputeQueue.h:20
Interface to run a workload on the GPU.
Definition ComputeSystem.h:16
Definition DebugRenderer.h:47
Class that holds 3 floats. Used as a storage class. Convert to Vec3 for calculations.
Definition Float3.h:13
Class that holds 4 float values. Convert to Vec4 to perform calculations.
Definition Float4.h:11
Definition Hair.h:35
Ref< ComputeBuffer > mConstantsCB
Definition Hair.h:214
Ref< ComputeBuffer > mVelocityAndDensityReadBackCB
Definition Hair.h:222
void SetScalpVerticesCB(ComputeBuffer *inBuffer)
Ability to externally provide the scalp vertices buffer. This allows skipping skinning the scalp duri...
Definition Hair.h:58
Quat mPrevRotation
Definition Hair.h:188
StridedPtr< const Float3 > GetAngularVelocities() const
Definition Hair.h:105
Ref< ComputeBuffer > mShapeVerticesCB
Definition Hair.h:205
Ref< ComputeBuffer > mScalpVerticesCB
Definition Hair.h:199
void SetRenderPositionsCB(ComputeBuffer *inBuffer)
Allow setting the render vertices buffer externally in case it has special requirements for the calli...
Definition Hair.h:73
RenderPositionsToFloat3 mRenderPositionsToFloat3
Definition Hair.h:196
Ref< ComputeBuffer > mShapeIndicesCB
Definition Hair.h:206
Ref< ComputeBuffer > mScalpJointMatricesCB
Definition Hair.h:198
void SetRotation(QuatArg inRotation)
Definition Hair.h:48
ComputeBuffer * GetScalpTrianglesCB() const
Skinned scalp triangle indices.
Definition Hair.h:87
ERenderStrandColor
Definition Hair.h:111
Quat mRotation
Definition Hair.h:189
Ref< ComputeBuffer > mTargetPositionsCB
Definition Hair.h:201
ComputeBuffer * GetRenderPositionsCB() const
Render positions of the hair strands (see HairSettings::mRenderStrands to see where each strand start...
Definition Hair.h:91
const Float3 * GetPositions() const
Definition Hair.h:102
std::function< void(ComputeBuffer *, Float3 *, uint)> RenderPositionsToFloat3
Function that converts the render positions buffer to Float3 vertices for debugging purposes....
Definition Hair.h:67
Ref< ComputeBuffer > mShapePlanesCB
Definition Hair.h:204
RefConst< HairSettings > mSettings
Definition Hair.h:184
Ref< ComputeBuffer > mRenderPositionsReadBackCB
Definition Hair.h:223
Array< Ref< ComputeBuffer > > mIterationConstantsCB
Definition Hair.h:215
Ref< ComputeBuffer > mPreviousPositionsCB
Definition Hair.h:210
Ref< ComputeBuffer > mVelocitiesCB
Definition Hair.h:212
void OnTeleported()
The hair will be initialized in its default pose with zero velocity at the new position and rotation ...
Definition Hair.h:55
Ref< ComputeBuffer > mTargetGlobalPoseTransformsCB
Definition Hair.h:202
StridedPtr< const Float3 > GetVelocities() const
Definition Hair.h:104
Ref< ComputeBuffer > mCollisionShapesCB
Definition Hair.h:208
RMat44 GetWorldTransform() const
Definition Hair.h:49
ComputeBuffer * GetPositionsCB() const
Note transposed for better memory access.
Definition Hair.h:88
Ref< ComputeBuffer > mGlobalPoseTransformsCB
Definition Hair.h:203
const HairSettings * GetHairSettings() const
Access to the hair settings object which contains the configuration of the hair.
Definition Hair.h:52
ComputeBuffer * GetVelocityAndDensityCB() const
Velocity grid.
Definition Hair.h:90
const Float3 * GetScalpVertices() const
Access to the resulting simulation data (only valid when ReadBackGPUState has been called and the buf...
Definition Hair.h:101
Ref< ComputeBuffer > mVelocitiesReadBackCB
Definition Hair.h:221
ComputeBuffer * GetScalpVerticesCB() const
Access to the resulting simulation data.
Definition Hair.h:86
const Float4 * GetGridVelocityAndDensity() const
Definition Hair.h:106
const Float3 * GetRenderPositions() const
Definition Hair.h:107
Ref< ComputeBuffer > mMaterialsCB
Definition Hair.h:209
void OverrideRenderPositionsCB(const RenderPositionsToFloat3 &inRenderPositionsToFloat3)
Enable externally set render vertices buffer (with potentially different vertex layout)....
Definition Hair.h:70
Ref< ComputeBuffer > mCollisionPlanesCB
Definition Hair.h:207
void SetPosition(RVec3Arg inPosition)
Position and rotation of the hair in world space.
Definition Hair.h:47
Ref< ComputeBuffer > mRenderPositionsCB
Definition Hair.h:216
Ref< ComputeBuffer > mPositionsCB
Definition Hair.h:211
Ref< ComputeBuffer > mPositionsReadBackCB
Definition Hair.h:220
ComputeBuffer * GetVelocitiesCB() const
Note transposed for better memory access.
Definition Hair.h:89
void SetScalpToHead(Mat44Arg inMat)
When skipping skinning, this allow specifying a transform that transforms the scalp mesh into head sp...
Definition Hair.h:64
ObjectLayer mLayer
Definition Hair.h:191
RVec3 mPosition
Definition Hair.h:187
Ref< ComputeBuffer > mVelocityAndDensityCB
Definition Hair.h:213
RVec3 mPrevPosition
Definition Hair.h:186
void SetScalpTrianglesCB(ComputeBuffer *inBuffer)
Ability to externally provide the scalp triangle indices buffer. This allows skipping skinning the sc...
Definition Hair.h:61
const Quat * GetRotations() const
Definition Hair.h:103
Ref< ComputeBuffer > mScalpTrianglesCB
Definition Hair.h:200
Ref< ComputeBuffer > mScalpVerticesReadBackCB
Definition Hair.h:219
Gradient along a hair strand of a value, e.g. compliance, friction, etc.
Definition HairSettings.h:110
Definition HairSettings.h:151
This class defines the setup of a hair groom, it can be shared between multiple hair instances.
Definition HairSettings.h:22
This class loads the shaders used by the hair system. This can be shared among all hair instances.
Definition HairShaders.h:14
Holds a 4x4 matrix of floats, but supports also operations on the 3x3 upper left part of the matrix.
Definition Mat44.h:13
static JPH_INLINE Mat44 sIdentity()
Identity matrix.
Definition Mat44.inl:35
static JPH_INLINE Mat44 sRotationTranslation(QuatArg inR, Vec3Arg inT)
Get matrix that rotates and translates.
Definition Mat44.inl:149
Class that makes another class non-copyable. Usage: Inherit from NonCopyable.
Definition NonCopyable.h:11
Definition PhysicsSystem.h:30
Definition Quat.h:33
Definition Reference.h:166
Definition Reference.h:110
Base class for all shapes (collision volume of a body). Defines a virtual interface for collision det...
Definition Shape.h:185
Definition StridedPtr.h:14
Definition Vec3.h:17
Definition Hair.h:122
Definition Hair.h:151
RefConst< Shape > mShape
Definition Hair.h:159
Vec3 mLinearVelocity
Definition Hair.h:157
LeafShape()=default
Mat44 mTransform
Definition Hair.h:155
Vec3 mAngularVelocity
Definition Hair.h:158
Vec3 mScale
Definition Hair.h:156
LeafShape(Mat44Arg inTransform, Vec3Arg inScale, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity, const Shape *inShape)
Definition Hair.h:153
Definition Hair.h:164
Array< LeafShape > mShapes
Definition Hair.h:178
bool mNeedsCollision
Definition Hair.h:168
float mTwoDivDeltaTime
Definition Hair.h:175
float mInvDeltaTimeSq
Definition Hair.h:174
float mHalfDeltaTime
Definition Hair.h:173
bool mNeedsGrid
Definition Hair.h:169
Quat mDeltaTransformQuat
Definition Hair.h:166
Vec3 mSubStepGravity
Definition Hair.h:177
float mDeltaTime
Definition Hair.h:172
uint mNumIterations
Definition Hair.h:167
bool mGlobalPoseOnly
Definition Hair.h:170
Mat44 mDeltaTransform
Definition Hair.h:165
bool mHasTransformChanged
Definition Hair.h:171
float mTimeRatio
Definition Hair.h:176