There are 3 issues
I found a solution. But it needs additinal functions in NvCloth.
[Link Removed]
[Link Removed]
// code placeholder void FClothingSimulationNv::UpdateLod(int32 InPredictedLod, const FTransform& ComponentToWorld, const TArray<FTransform>& CSTransforms, bool bForceNoRemap, bool bForceActorChecks) ... if(bOldLodMapped && !bForceNoRemap) { FClothingActorNv::FActorLodData& CurrLodData = Actor.LodData[OldClothingLod]; // the number of LODs we've passed through, we can only reskin the incoming mesh if we've stepped 1 LOD const int32 NumLodsPassed = FMath::Abs(OldClothingLod - PredictedClothingLod); const uint32 NumOldParticles = CurrLodData.Cloth->getNumParticles(); nv::cloth::Range<const physx::PxVec4> OldLodParticles = nv::cloth::readCurrentParticles(*CurrLodData.Cloth); #if 1 //fix part 1 : restore previous particle locations nv::cloth::Range<const physx::PxVec4> OldLodPreviousParticles = nv::cloth::readPreviousParticles(*CurrLodData.Cloth); #endif // Remove the old LOD from the solver Solver->removeCloth(Actor.LodData[OldClothingLod].Cloth); nv::cloth::Range<physx::PxVec4> OldAccelerations = CurrLodData.Cloth->getParticleAccelerations(); Solver->addCloth(Actor.LodData[PredictedClothingLod].Cloth); if(NumLodsPassed == 1) { // Reposition particles skinned to outgoing LOD bool bLodTransitionUp = OldClothingLod < PredictedClothingLod; FClothLODData& NewLodAssetData = Actor.AssetCreatedFrom->LodData[PredictedClothingLod]; TArray<FMeshToMeshVertData>& SkinData = bLodTransitionUp ? NewLodAssetData.TransitionUpSkinData : NewLodAssetData.TransitionDownSkinData; for(int32 ParticleIndex = 0; ParticleIndex < NumNewParticles; ++ParticleIndex) { // Do some simple skinning, we only care about positions for this as particles are just // positions inside the solver. FMeshToMeshVertData& VertData = SkinData[ParticleIndex]; const FVector A = P2UVector(OldLodParticles[VertData.SourceMeshVertIndices[0]]); const FVector B = P2UVector(OldLodParticles[VertData.SourceMeshVertIndices[1]]); const FVector C = P2UVector(OldLodParticles[VertData.SourceMeshVertIndices[2]]); #if 1 const FVector PA = P2UVector(OldLodPreviousParticles[VertData.SourceMeshVertIndices[0]]); const FVector PB = P2UVector(OldLodPreviousParticles[VertData.SourceMeshVertIndices[1]]); const FVector PC = P2UVector(OldLodPreviousParticles[VertData.SourceMeshVertIndices[2]]); #endif // CurrentNormals still contains the normals from the old LOD, which will have been // calculated at the end of the last simulation step. const FVector& NA = Actor.CurrentNormals[VertData.SourceMeshVertIndices[0]]; const FVector& NB = Actor.CurrentNormals[VertData.SourceMeshVertIndices[1]]; const FVector& NC = Actor.CurrentNormals[VertData.SourceMeshVertIndices[2]]; const physx::PxVec4& AA = OldAccelerations[VertData.SourceMeshVertIndices[0]]; const physx::PxVec4& AB = OldAccelerations[VertData.SourceMeshVertIndices[1]]; const physx::PxVec4& AC = OldAccelerations[VertData.SourceMeshVertIndices[2]]; #if 1 const FVector FinalPosition = VertData.PositionBaryCoordsAndDist.X * A + NA * VertData.PositionBaryCoordsAndDist.W + VertData.PositionBaryCoordsAndDist.Y * B + NB * VertData.PositionBaryCoordsAndDist.W + VertData.PositionBaryCoordsAndDist.Z * C + NC * VertData.PositionBaryCoordsAndDist.W; const FVector FinalPreviousPosition = VertData.PositionBaryCoordsAndDist.X * PA + NA * VertData.PositionBaryCoordsAndDist.W + VertData.PositionBaryCoordsAndDist.Y * PB + NB * VertData.PositionBaryCoordsAndDist.W + VertData.PositionBaryCoordsAndDist.Z * PC + NC * VertData.PositionBaryCoordsAndDist.W; #else FVector FinalPosition = VertData.PositionBaryCoordsAndDist.X * A + NA * VertData.PositionBaryCoordsAndDist.W + VertData.PositionBaryCoordsAndDist.Y * B + NB * VertData.PositionBaryCoordsAndDist.W + VertData.PositionBaryCoordsAndDist.Z * C + NC * VertData.PositionBaryCoordsAndDist.W; #endif physx::PxVec4 FinalAcceleration = VertData.PositionBaryCoordsAndDist.X * AA + VertData.PositionBaryCoordsAndDist.Y * AB + VertData.PositionBaryCoordsAndDist.Z * AC; NewLodParticles[ParticleIndex] = physx::PxVec4(U2PVector(FinalPosition), NewLodParticles[ParticleIndex].w); #if 1 NewLodPrevParticles[ParticleIndex] = physx::PxVec4(U2PVector(FinalPreviousPosition), NewLodParticles[ParticleIndex].w); #else NewLodPrevParticles[ParticleIndex] = physx::PxVec4(U2PVector(FinalPosition), NewLodParticles[ParticleIndex].w); #endif NewAccelerations[ParticleIndex] = FinalAcceleration; } } else { // We've passed more than one LOD, and we don't have transition data for all permutations, just use ref pose for(int32 ParticleIndex = 0; ParticleIndex < NumNewParticles; ++ParticleIndex) { NewLodParticles[ParticleIndex] = NewLodData.Px_RestPositions[ParticleIndex]; NewLodPrevParticles[ParticleIndex] = NewLodData.Px_RestPositions[ParticleIndex]; NewAccelerations[ParticleIndex] = physx::PxVec4(0.0f); } } #if 1 //fix part 2 : store transform from a last cloth instance instead current transform NewLodData.Cloth->setTranslation(CurrLodData.Cloth->getTranslation()); NewLodData.Cloth->setRotation(CurrLodData.Cloth->getRotation()); #else FTransform SimRootTransform = CSTransforms[Actor.AssetCreatedFrom->ReferenceBoneIndex] * ComponentToWorld; NewLodData.Cloth->setTranslation(U2PVector(SimRootTransform.GetTranslation())); NewLodData.Cloth->setRotation(U2PQuat(SimRootTransform.GetRotation())); #endif NewLodData.Cloth->clearInertia(); #if 1 //fix part 3 : Add new functions in NvCloth and then call them for restorng LinearVelocity cleared by clearInertica function. NewLodData.Cloth->setLinearVelocity(CurrLodData.Cloth->getLinearVelocity()); NewLodData.Cloth->setAngularVelocity(CurrLodData.Cloth->getAngularVelocity()); #endif Actor.CurrentLodIndex = PredictedClothingLod; } else
Changing cloth LoD with moving skeletal mesh is trigger.
If skeletal mesh has no velocity, This issue will not happen.
[Link Removed]
How does TextureRenderTarget2D get TArray<uint8> type data?
Why does the REMOVE method of map container remove elements have memory leaks?
How to delete some elements correctly when deleting an array loop?
What is the cause of the packaging error falling back to 'GameUserSettings' in ue5?
How do I set a material as a post-processing material?
UMG RichText not appear image when packaged
There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-77100 in the post.
3 |
Component | UE - Simulation - Physics - Character |
---|---|
Affects Versions | 4.22.3 |
Created | Jul 11, 2019 |
---|---|
Resolved | Jul 19, 2019 |
Updated | Jun 30, 2020 |