void UNavCollision::Setup(UBodySetup* BodySetup) { // Create meshes from cooked data if not already done if (bHasConvexGeometry || BodySetup == NULL) { return; } BodySetupGuid = BodySetup->BodySetupGuid; // Make sure all are cleared before we start ClearCollision(); if (ShouldUseConvexCollision()) { // Find or create cooked navcollision data FByteBulkData* FormatData = GetCookedData(NAVCOLLISION_FORMAT); if (!bForceGeometryRebuild && FormatData) { // if it's not being already processed if (FormatData->IsLocked() == false) { // Create physics objects FNavCollisionDataReader CookedDataReader(*FormatData, TriMeshCollision, ConvexCollision, ConvexShapeIndices); bHasConvexGeometry = true; } } else { GatherCollision(); } } }
void UBodySetup::CreatePhysicsMeshes() { #if WITH_PHYSX // Create meshes from cooked data if not already done if(bCreatedPhysicsMeshes) { return; } // Find or create cooked physics data static FName PhysicsFormatName(FPlatformProperties::GetPhysicsFormat()); FByteBulkData* FormatData = GetCookedData(PhysicsFormatName); if( FormatData ) { if (FormatData->IsLocked()) { // seems it's being already processed return; } FPhysXFormatDataReader CookedDataReader(*FormatData); if (CollisionTraceFlag != CTF_UseComplexAsSimple) { bool bNeedsCooking = bGenerateNonMirroredCollision && CookedDataReader.ConvexMeshes.Num() != AggGeom.ConvexElems.Num(); bNeedsCooking = bNeedsCooking || (bGenerateMirroredCollision && CookedDataReader.ConvexMeshesNegX.Num() != AggGeom.ConvexElems.Num()); if (bNeedsCooking) //Because of bugs it's possible to save with out of sync cooked data. In editor we want to fixup this data { #if WITH_EDITOR InvalidatePhysicsData(); CreatePhysicsMeshes(); return; #endif } } ClearPhysicsMeshes(); if (CollisionTraceFlag != CTF_UseComplexAsSimple) { ensure(!bGenerateNonMirroredCollision || CookedDataReader.ConvexMeshes.Num() == 0 || CookedDataReader.ConvexMeshes.Num() == AggGeom.ConvexElems.Num()); ensure(!bGenerateMirroredCollision || CookedDataReader.ConvexMeshesNegX.Num() == 0 || CookedDataReader.ConvexMeshesNegX.Num() == AggGeom.ConvexElems.Num()); //If the cooked data no longer has convex meshes, make sure to empty AggGeom.ConvexElems - otherwise we leave NULLS which cause issues, and we also read past the end of CookedDataReader.ConvexMeshes if ((bGenerateNonMirroredCollision && CookedDataReader.ConvexMeshes.Num() == 0) || (bGenerateMirroredCollision && CookedDataReader.ConvexMeshesNegX.Num() == 0)) { AggGeom.ConvexElems.Empty(); } for (int32 ElementIndex = 0; ElementIndex < AggGeom.ConvexElems.Num(); ElementIndex++) { FKConvexElem& ConvexElem = AggGeom.ConvexElems[ElementIndex]; if (bGenerateNonMirroredCollision) { ConvexElem.ConvexMesh = CookedDataReader.ConvexMeshes[ElementIndex]; FPhysxSharedData::Get().Add(ConvexElem.ConvexMesh); } if (bGenerateMirroredCollision) { ConvexElem.ConvexMeshNegX = CookedDataReader.ConvexMeshesNegX[ElementIndex]; FPhysxSharedData::Get().Add(ConvexElem.ConvexMeshNegX); } } } if(bGenerateNonMirroredCollision) { TriMesh = CookedDataReader.TriMesh; FPhysxSharedData::Get().Add(TriMesh); } if(bGenerateMirroredCollision) { TriMeshNegX = CookedDataReader.TriMeshNegX; FPhysxSharedData::Get().Add(TriMeshNegX); } } else { ClearPhysicsMeshes(); // Make sure all are cleared then } // Clear the cooked data if (!GIsEditor && !bSharedCookedData) { CookedFormatData.FlushData(); } bCreatedPhysicsMeshes = true; #endif }