Files
UnrealEngineUWP/Engine/Source/Developer/MeshMergeUtilities/Private/MeshMergeHelpers.cpp

1222 lines
48 KiB
C++
Raw Normal View History

// Copyright Epic Games, Inc. All Rights Reserved.
#include "MeshMergeHelpers.h"
#include "Engine/MapBuildDataRegistry.h"
#include "Engine/MeshMerging.h"
#include "MaterialOptions.h"
#include "StaticMeshAttributes.h"
#include "StaticMeshOperations.h"
#include "Misc/PackageName.h"
#include "MaterialUtilities.h"
#include "Components/SkeletalMeshComponent.h"
#include "Components/SplineMeshComponent.h"
#include "Components/SkinnedMeshComponent.h"
#include "Rendering/SkeletalMeshModel.h"
#include "SkeletalMeshTypes.h"
#include "SkeletalRenderPublic.h"
#include "UObject/UObjectBaseUtility.h"
#include "UObject/Package.h"
#include "Materials/Material.h"
#include "Misc/ScopedSlowTask.h"
#include "Modules/ModuleManager.h"
#include "HierarchicalLODUtilitiesModule.h"
#include "MeshMergeData.h"
#include "IHierarchicalLODUtilities.h"
#include "Engine/MeshMergeCullingVolume.h"
#include "Landscape.h"
#include "LandscapeProxy.h"
#include "Editor.h"
#include "Engine/StaticMesh.h"
#include "PhysicsEngine/ConvexElem.h"
#include "PhysicsEngine/BodySetup.h"
#include "MeshUtilities.h"
#include "ImageUtils.h"
#include "LandscapeHeightfieldCollisionComponent.h"
#include "IMeshReductionManagerModule.h"
#include "LayoutUV.h"
#include "Components/InstancedStaticMeshComponent.h"
//DECLARE_LOG_CATEGORY_CLASS(LogMeshMerging, Verbose, All);
static TAutoConsoleVariable<int32> CVarMeshMergeStoreImposterInfoInUVs(
TEXT("r.MeshMerge.StoreImposterInfoInUVs"),
0,
TEXT("Determines whether or not to store imposter info (position.xy in UV2, position.z + scale in UV3) in the merged mesh UV channels\n")
TEXT("0: Do not store imposters info in UVs (default)\n")
TEXT("1: Store imposter info in UVs (legacy)\n"),
ECVF_Default);
void FMeshMergeHelpers::ExtractSections(const UStaticMeshComponent* Component, int32 LODIndex, TArray<FSectionInfo>& OutSections)
{
static UMaterialInterface* DefaultMaterial = UMaterial::GetDefaultMaterial(MD_Surface);
Copying //UE4/Dev-AnimPhys to //UE4/Dev-Main (Source: //UE4/Dev-AnimPhys @ 4062005) #lockdown Nick.Penwarden ============================ MAJOR FEATURES & CHANGES ============================ Change 4005617 by Danny.Bouimad Fixing TM-AnimPhys lighting so it works on all platforms #jira UEENGQA-19924 Change 4014898 by Aaron.McLeran Adding simple delay feature Change 4025071 by Lina.Halper Fix and more potential fix for invalid bone index issue http://crashreporter/Buggs/Show/2052839 http://crashreporter/Crashes/Show/46656562 #jira: UE-51931 Change 4042493 by Lina.Halper Fix issue with sequence evaluator to handle properly when jumps from end to front or front to end #jira: UE-58429 Change 4042892 by Lina.Halper Fix issue with being able to drag/drop montage onto anim track in sequencer #jira: UE-57863 Change 4043553 by Ethan.Geller #jira UE-58340 Handle calls to FVoiceCaptureWindows::GetVoiceData outside of existing data calls. #rb none Change 4043613 by Lina.Halper Fix issue with incorrect usage of staticclass #jira: UE-54413 Change 4044069 by James.Golding PR #4455: Add FAnimNode_StateMachine subclassing support. (Contributed by redfeatherplusplus) #jira UE-54599 Change 4044070 by James.Golding PR #4349: Final points on a line test were broken, changed Plane.PlaneDot to FM. (Contributed by DSDambuster) #jira UE-53554 Change 4044072 by James.Golding Add ENGINE_API to UPhysicsHandleComponent so it can be subclassed #jira UE-56397 Change 4044073 by James.Golding PR #4611: Expose a few API's so it's possible to make custom anim graph nodes using these objects. (Contributed by ill) #jira UE-57004 Change 4044075 by James.Golding PR #4618: Bugfix: typo in path for CustomMeshComponent (case error) (Contributed by malavon) #jira UE-57077 Change 4044077 by James.Golding Add ClassGroup to some components #jira UE-57587, UE-57609 Change 4044080 by James.Golding PR #4515: Adding API export macro to ACableActor (Contributed by maxtunel) #jira UE-55515 Change 4044082 by James.Golding Remove unused CopySkinnedModelData function #jira UE-57623 Change 4044083 by James.Golding Fix per-poly collision for skel meshes. Make sure to call UpdateKinematicBonesToAnim if bEnablePerPolyCollision is set, even if no bodies Integration of CL 3971421 from Release-4.19 stream #jira UE-56405 Change 4044084 by James.Golding Add option to preview 'fixed bounds' in SkelMesh editors. Change 4044086 by James.Golding Remove unused RigidInfluenceIndex from CPU skinning code Change 4044310 by James.Golding Roll back changes to make PhysX cool fails a log instead of warning (CL 3995372, UE-56466), now that content is fixed Change 4044416 by Lina.Halper Provide BP interface to get curve list of names #jira: UE-52623 Change 4044419 by Lina.Halper added notification for updating pose asset #jira: UE-56233 Change 4046929 by Ethan.Geller #jira none add my developer folder to QAGame. #fyi dan.reynolds Change 4047064 by Ethan.Geller [Dev-AnimPhys] #jira UE-57890 add additional binaries for Steam Audio to LibPhonon.Build.cs. #rb none Change 4047564 by Lina.Halper Fix issue of not regenerating when reimport mesh #jira: UE-58284 Change 4047630 by Ethan.Geller Fix syntax error in libPhonon. #jira none #rb none Change 4048050 by Thomas.Sarkanen Allowed "Follow Bone" to be popped out of the menu into the viewport This allows for quick re-selection of the bone to follow, avoiding multiple clicks Tweaks and extends the "pinned command list" system to allow dynamic text in labels and labels to be hidden. #jira UE-53070 - Follow bone - Follow selected bone Change 4048064 by Thomas.Sarkanen Validate any bone references during compilation Bone references that are set to something other than NAME_None will be verified against the skeleton. Updated various anim nodes to call the base class ValidateAnimNodeDuringCompilation #jira UE-55680 - Anim graph nodes that use FBoneReference all need validation in ValidateAnimNodeDuringCompilation Change 4048468 by James.Golding PR #4319: Allow UAnimNotify_PlayMontageNotify to be inherited by other dlls (Contributed by DSDambuster) #jira UE-53390 Change 4048470 by James.Golding Implement ApplyWorldOffset to CableComponent, to handle origin shifting #jira UE-53560 Change 4048471 by James.Golding PR #4396: fix cachebones for subclasses of FAnimNode_SkeletalControlBase (Contributed by tmiv) #jira UE-53799 Change 4048474 by James.Golding PR #4423: Rename confusing argument in LineBoxIntersection (Contributed by Hybrid0) #jira UE-54145 Change 4048485 by James.Golding Fix compile error display from PoseDriver node #jira UE-58306 Change 4048489 by James.Golding Finish support for ProceduralMeshComponent supporting multiple UV channels #jira UE-54049 Change 4048678 by Thomas.Sarkanen Allowing blend space samples to be optionally moved off-grid Grid samples are now each optionally snapped. #jira UE-56116 - Allow blend spaces to optionally use off-grid sample points Change 4048773 by Lina.Halper Support pose factory with name input #jira: UE-55859 Change 4048844 by David.Hill Material Proxy Settings Updating the max on the material proxy texture size - old value could cause int32 overflow. #jira: UE-55441 Change 4049464 by Lina.Halper update curve is expensive, and we're doing multiple times with same curve sets. I'm changing it so that it only updates main, and copy from main instance to sub/post. #jira: UE-58459 Change 4050939 by Aaron.McLeran PR #4649: Activated reverbs will now take priority when world settings are used (i.e. no volume proxy is in use) (Contributed by Brandon-Wilson) #jira UE-57546 Change 4050954 by Aaron.McLeran PR #4594: Added class type to allow inherited versions of UAudioComponents to be created (Contributed by korypostma) #jira UE-56454 Change 4050960 by Aaron.McLeran Attempt to fix linux build. Change 4051247 by James.Golding Fix ProcMeshComp UpdateSection not copying all UV sets Add test case for ProcMeshComp with multiple UVs #jira UE-54049 Change 4051250 by James.Golding Add bUseHighPrecisionTangentBasis option to SkeletalMesh Change SkeletalMesh source data to store tangents at higher precision #jira UE-58525 Change 4051616 by Thomas.Sarkanen Mass scale is no longer incorrectly clamped This now allows mass scales below 0.01 and above 100. #jira UE-49572 - MassScale has some edge cases for skeletal mesh component and small numbers Change 4051619 by Thomas.Sarkanen Fixed notify drag/drop on high DPI displays #jira UE-55690 - Animation Notifies Do Not Move Past the Center of Timeline On a High DPI Display Change 4051626 by Thomas.Sarkanen Fix anim dynamics debug rendering #jira UE-53902 - Anim Dynamics node is missing wireframe simulation box in preview #jira UE-57983 - GitHub 4674 : UE-57910 Fix the angular limits display issue while selecting the AnimDynamics node Change 4051628 by Thomas.Sarkanen Constraints and bodies now rotate in their own local space in the physics asset editor When local coordinate system is applied #jira UE-50345 - rotating constraints or bodies in Phat with local axis Change 4051634 by Thomas.Sarkanen Automatic rules for state transitions are now shown in tooltips #jira UE-57689 - Animation State Machine Transitions that use bAutomaticRuleBasedOnSequencePlayerInState, should indicate that in the transition Change 4051636 by Thomas.Sarkanen NotifyTriggerChance is now hidden for nodify states as it has no effect #jira UE-55351 - NotifyTriggerChance should be grayed out for UAnimNotifyState Change 4051669 by Thomas.Sarkanen Fixed accidental operation of pinned commands when closing them #jira UE-54051 - Unpinning settings will toggle the next setting Change 4051671 by Thomas.Sarkanen Fix crash importing skeletal mesh with no vertices Not a fix for the jira, but found while investigating #jira UE-56330 - FBX Files Do Not Import After Using the Facial Anim Importer Unless Project is Reopened Change 4051684 by James.Golding Fix high precision tangents when CPU skinning and mesh merging Remember bExistingUseHighPrecisionTangentBasis when re-importing SkelMesh #jira UE-58525 Change 4051686 by James.Golding PR #4297: Output animation name with ensure() - useful when debugging (Contributed by DSDambuster) #jira UE-53259 Change 4051801 by Jurre.deBaare A BlendSpace that puts the same asset on samples can stop its own animation on Switch #fix Ensure that we don't cause divide-by-zero situations when sampling blendspace data #jira UE-54030 Change 4051806 by Jurre.deBaare Fix geometry cache reimport + serialization issues Change 4051807 by Jurre.deBaare Currently, it's not possible to assigned a material to a Geometry Cache .uasset #fix EditAnywhere rather than VisibleAnywhere #jira UE-58212 Change 4051809 by Jurre.deBaare GeomCache: Crash/Bug: When importing file #fix Ensure that we have a valid first frame when trying to import a sequence, if not error-out #jira UE-58285 Change 4051813 by Jurre.deBaare GeomCache: Bug: Normals Broken #jira UE-58287 GeomCache - Normals are Bad on Import #jira UE-58283 #fix ensure that we triangulate mesh attributes when necessary #misc per-attribute indices check Change 4051816 by Jurre.deBaare Alembic QOL - Fix issue with reimport object flags not being applied - Now also store sampling data as part of Alembic asset import data Change 4051817 by Jurre.deBaare PR #4550: Fixes bug where "Merge Actors" or HLOD proxies result in too many mesh sections (Contributed by trond) #fix Integrated pull-request in different form #jira UE-55976 Change 4051818 by Jurre.deBaare Emissive isn't baked correctly in TM-MeshbakeMap #fix ensure that we OR and Max the material flags and emissive scale #jira UE-54889 Change 4051819 by Jurre.deBaare Crash on project load when GeometryCache plugin is disabled #fix No longer force-load the geometry cache module as it was moved to be a plugin #jira UE-57875 Change 4051820 by Jurre.deBaare CLONE - Editor crash when Propagating Vertex Colors to Asset's source mesh #fix IsValidIndex check #jira UE-57127 Vertex painting Change 4051828 by Jurre.deBaare Merging negative-scaled actors breaks materials #fix Make sure we also reverse the section indices when a static mesh has a mirrored transform #jira UE-56953 Change 4051834 by Jurre.deBaare Unclear warnings when generating clusters in persistent level when sublevels have HLOD disabled #fix improved warning text + added uobject link to level in content browser #jira UE-55734 Change 4051993 by Jurre.deBaare Update Alembic automated test ground truth #jira none Change 4052937 by James.Golding Remove now-unused version (merged change to skel source data from Main instead) Change 4053291 by Aaron.McLeran Fix for CIS #jira none Change 4053375 by Aaron.McLeran #jira UE-58716 Allow ability to bypass volume-weighting with using sound wave priority Change 4057170 by Thomas.Sarkanen Fix shadow variable warning #jira UE-58806 - Linux: Shadow Variable Warnings building Editor - PhysicsAssetEditorEditMode.cpp Change 4057653 by Lina.Halper Fix the issue with showing same item multiple times when opening control rig blueprint many times #jira: UE-58107 Change 4057701 by Jurre.deBaare //UE4/Dev-AnimPhys - Step 'Run Automated Tests' has completed with 13 Errors #fix reupdate alembic ground truths, little bit of a weird state #jira UE-58818 Change 4057710 by Ethan.Geller [Dev-AnimPhys] #jira UE-58004 Early exit if finish was called before StartSubmixRecording. #rb Aaron.McLeran Change 4059295 by Ethan.Geller #jira UE-58004 Reduce logs from fatal to error, fix serialize crash. #rb aaron.mcleran Change 4061061 by Aaron.McLeran Fixing animphys build from recent merge from main. #jira UE-58909 Change 4053154 by Aaron.McLeran #jira UE-58708 Fix to mic component to reduce clicks/pops on mic input. Fix was to simplify the way audio is copied from mic input. This change was used on the GDC demo floor for a number of features. [CL 4062611 by Aaron McLeran in Main branch]
2018-05-09 18:45:58 -04:00
const UStaticMesh* StaticMesh = Component->GetStaticMesh();
TArray<FName> MaterialSlotNames;
for (const FStaticMaterial& StaticMaterial : StaticMesh->GetStaticMaterials())
{
#if WITH_EDITOR
MaterialSlotNames.Add(StaticMaterial.ImportedMaterialSlotName);
#else
MaterialSlotNames.Add(StaticMaterial.MaterialSlotName);
#endif
}
for (const FStaticMeshSection& MeshSection : StaticMesh->GetRenderData()->LODResources[LODIndex].Sections)
{
// Skip empty sections
if (MeshSection.NumTriangles == 0)
{
continue;
}
// Retrieve material for this section
UMaterialInterface* StoredMaterial = Component->GetMaterial(MeshSection.MaterialIndex);
// Make sure the resource actual exists, otherwise use default material
StoredMaterial = (StoredMaterial != nullptr) && StoredMaterial->GetMaterialResource(GMaxRHIFeatureLevel) ? StoredMaterial : DefaultMaterial;
// Populate section data
FSectionInfo SectionInfo;
SectionInfo.Material = StoredMaterial;
SectionInfo.MaterialIndex = MeshSection.MaterialIndex;
SectionInfo.MaterialSlotName = MaterialSlotNames.IsValidIndex(MeshSection.MaterialIndex) ? MaterialSlotNames[MeshSection.MaterialIndex] : NAME_None;
SectionInfo.StartIndex = MeshSection.FirstIndex / 3;
SectionInfo.EndIndex = SectionInfo.StartIndex + MeshSection.NumTriangles;
if (MeshSection.bEnableCollision)
{
SectionInfo.EnabledProperties.Add(GET_MEMBER_NAME_CHECKED(FStaticMeshSection, bEnableCollision));
}
if (MeshSection.bCastShadow && Component->CastShadow)
{
SectionInfo.EnabledProperties.Add(GET_MEMBER_NAME_CHECKED(FStaticMeshSection, bCastShadow));
}
OutSections.Add(SectionInfo);
}
}
void FMeshMergeHelpers::ExtractSections(const USkeletalMeshComponent* Component, int32 LODIndex, TArray<FSectionInfo>& OutSections)
{
static UMaterialInterface* DefaultMaterial = UMaterial::GetDefaultMaterial(MD_Surface);
FSkeletalMeshModel* Resource = Component->SkeletalMesh->GetImportedModel();
checkf(Resource->LODModels.IsValidIndex(LODIndex), TEXT("Invalid LOD Index"));
TArray<FName> MaterialSlotNames = Component->GetMaterialSlotNames();
const FSkeletalMeshLODInfo* LODInfoPtr = Component->SkeletalMesh->GetLODInfo(LODIndex);
check(LODInfoPtr);
const FSkeletalMeshLODModel& Model = Resource->LODModels[LODIndex];
for (int32 SectionIndex = 0; SectionIndex < Model.Sections.Num(); ++SectionIndex)
{
const FSkelMeshSection& MeshSection = Model.Sections[SectionIndex];
// Retrieve material for this section
int32 MaterialIndex = MeshSection.MaterialIndex;
if (LODInfoPtr->LODMaterialMap.IsValidIndex(SectionIndex) && LODInfoPtr->LODMaterialMap[SectionIndex] != INDEX_NONE)
{
MaterialIndex = LODInfoPtr->LODMaterialMap[SectionIndex];
}
UMaterialInterface* StoredMaterial = Component->GetMaterial(MaterialIndex);
// Make sure the resource actual exists, otherwise use default material
StoredMaterial = (StoredMaterial != nullptr) && StoredMaterial->GetMaterialResource(GMaxRHIFeatureLevel) ? StoredMaterial : DefaultMaterial;
FSectionInfo SectionInfo;
SectionInfo.Material = StoredMaterial;
SectionInfo.MaterialSlotName = MaterialSlotNames.IsValidIndex(MaterialIndex) ? MaterialSlotNames[MaterialIndex] : NAME_None;
if (MeshSection.bCastShadow && Component->CastShadow)
{
SectionInfo.EnabledProperties.Add(GET_MEMBER_NAME_CHECKED(FSkelMeshSection, bCastShadow));
}
if (MeshSection.bVisibleInRayTracing)
{
SectionInfo.EnabledProperties.Add(GET_MEMBER_NAME_CHECKED(FSkelMeshSection, bVisibleInRayTracing));
}
if (MeshSection.bRecomputeTangent)
{
SectionInfo.EnabledProperties.Add(GET_MEMBER_NAME_CHECKED(FSkelMeshSection, bRecomputeTangent));
}
OutSections.Add(SectionInfo);
}
}
void FMeshMergeHelpers::ExtractSections(const UStaticMesh* StaticMesh, int32 LODIndex, TArray<FSectionInfo>& OutSections)
{
static UMaterialInterface* DefaultMaterial = UMaterial::GetDefaultMaterial(MD_Surface);
for (const FStaticMeshSection& MeshSection : StaticMesh->GetRenderData()->LODResources[LODIndex].Sections)
{
// Retrieve material for this section
UMaterialInterface* StoredMaterial = StaticMesh->GetMaterial(MeshSection.MaterialIndex);
// Make sure the resource actual exists, otherwise use default material
StoredMaterial = (StoredMaterial != nullptr) && StoredMaterial->GetMaterialResource(GMaxRHIFeatureLevel) ? StoredMaterial : DefaultMaterial;
// Populate section data
FSectionInfo SectionInfo;
SectionInfo.Material = StoredMaterial;
SectionInfo.MaterialIndex = MeshSection.MaterialIndex;
#if WITH_EDITOR
SectionInfo.MaterialSlotName = StaticMesh->GetStaticMaterials().IsValidIndex(MeshSection.MaterialIndex) ? StaticMesh->GetStaticMaterials()[MeshSection.MaterialIndex].ImportedMaterialSlotName : NAME_None;
#else
SectionInfo.MaterialSlotName = StaticMesh->GetStaticMaterials().IsValidIndex(MeshSection.MaterialIndex) ? StaticMesh->GetStaticMaterials()[MeshSection.MaterialIndex].MaterialSlotName : NAME_None;
#endif
if (MeshSection.bEnableCollision)
{
SectionInfo.EnabledProperties.Add(GET_MEMBER_NAME_CHECKED(FStaticMeshSection, bEnableCollision));
}
if (MeshSection.bCastShadow)
{
SectionInfo.EnabledProperties.Add(GET_MEMBER_NAME_CHECKED(FStaticMeshSection, bCastShadow));
}
OutSections.Add(SectionInfo);
}
}
void FMeshMergeHelpers::ExpandInstances(const UInstancedStaticMeshComponent* InInstancedStaticMeshComponent, FMeshDescription& InOutMeshDescription)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FMeshMergeHelpers::ExpandInstances)
FMeshDescription CombinedMeshDescription;
FStaticMeshAttributes(CombinedMeshDescription).Register();
FTransform ComponentTransform = InInstancedStaticMeshComponent->GetComponentTransform();
FTransform ComponentTransformInv = ComponentTransform.Inverse();
// Reserve memory upfront
int32 NumInstances = InInstancedStaticMeshComponent->GetInstanceCount();
CombinedMeshDescription.ReserveNewVertices(InOutMeshDescription.Vertices().Num() * NumInstances);
CombinedMeshDescription.ReserveNewVertexInstances(InOutMeshDescription.VertexInstances().Num() * NumInstances);
CombinedMeshDescription.ReserveNewEdges(InOutMeshDescription.Edges().Num() * NumInstances);
CombinedMeshDescription.ReserveNewTriangles(InOutMeshDescription.Triangles().Num() * NumInstances);
FStaticMeshOperations::FAppendSettings AppendSettings;
for (int32 ChannelIdx = 0; ChannelIdx < FStaticMeshOperations::FAppendSettings::MAX_NUM_UV_CHANNELS; ++ChannelIdx)
{
AppendSettings.bMergeUVChannels[ChannelIdx] = true;
}
FMeshDescription InstanceMeshDescription;
for(const FInstancedStaticMeshInstanceData& InstanceData : InInstancedStaticMeshComponent->PerInstanceSMData)
{
InstanceMeshDescription = InOutMeshDescription;
FStaticMeshOperations::ApplyTransform(InstanceMeshDescription, ComponentTransformInv * FTransform(InstanceData.Transform) * ComponentTransform);
FStaticMeshOperations::AppendMeshDescription(InstanceMeshDescription, CombinedMeshDescription, AppendSettings);
}
InOutMeshDescription = CombinedMeshDescription;
}
static void RetrieveMeshInternal(const UStaticMesh* StaticMesh, const UStaticMeshComponent* StaticMeshComponent, int32 LODIndex, FMeshDescription& OutMeshDescription, bool bPropagateVertexColours)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FMeshMergeHelpers::RetrieveMeshInternal)
check(StaticMesh);
// Export the mesh data using static mesh render data
FMeshMergeHelpers::ExportStaticMeshLOD(StaticMesh->GetRenderData()->LODResources[LODIndex], OutMeshDescription, StaticMesh->GetStaticMaterials());
// Make sure the mesh is not irreparably malformed.
if (OutMeshDescription.VertexInstances().Num() <= 0)
{
return;
}
// If we have a component, use it to retrieve transform & vertex colors (if requested)
if (StaticMeshComponent)
{
// Transform mesh to world space
FTransform ComponentToWorldTransform = StaticMeshComponent->GetComponentTransform();
// Handle spline mesh deformation
const bool bIsSplineMeshComponent = StaticMeshComponent->IsA<USplineMeshComponent>();
if (bIsSplineMeshComponent)
{
const USplineMeshComponent* SplineMeshComponent = Cast<USplineMeshComponent>(StaticMeshComponent);
// Deform mesh data according to the Spline Mesh Component's data
FMeshMergeHelpers::PropagateSplineDeformationToMesh(SplineMeshComponent, OutMeshDescription);
}
// If specified propagate painted vertex colors into our raw mesh
if (bPropagateVertexColours)
{
FMeshMergeHelpers::PropagatePaintedColorsToMesh(StaticMeshComponent, LODIndex, OutMeshDescription);
}
// Transform raw mesh vertex data by the Static Mesh Component's component to world transformation
FStaticMeshOperations::ApplyTransform(OutMeshDescription, ComponentToWorldTransform);
}
FMeshBuildSettings BuildSettings;
// If editor data is not available, we won't have access to source model
const bool bHasSourceModels = StaticMesh->IsSourceModelValid(0);
if (bHasSourceModels)
{
// Imported meshes will have a valid mesh description
const bool bImportedMesh = bHasSourceModels ? false : StaticMesh->IsMeshDescriptionValid(LODIndex);
// Use build settings from base mesh for LOD entries that were generated inside Editor.
BuildSettings = bImportedMesh ? StaticMesh->GetSourceModel(LODIndex).BuildSettings : StaticMesh->GetSourceModel(0).BuildSettings;
}
// Figure out if we should recompute normals and tangents. By default generated LODs should not recompute normals
EComputeNTBsFlags ComputeNTBsOptions = EComputeNTBsFlags::BlendOverlappingNormals;
if (BuildSettings.bRemoveDegenerates)
{
// If removing degenerate triangles, ignore them when computing tangents.
ComputeNTBsOptions |= EComputeNTBsFlags::IgnoreDegenerateTriangles;
}
if (BuildSettings.bUseMikkTSpace)
{
ComputeNTBsOptions |= EComputeNTBsFlags::UseMikkTSpace;
}
FStaticMeshOperations::ComputeTriangleTangentsAndNormals(OutMeshDescription, 0.0f);
FStaticMeshOperations::RecomputeNormalsAndTangentsIfNeeded(OutMeshDescription, ComputeNTBsOptions);
}
void FMeshMergeHelpers::RetrieveMesh(const UStaticMeshComponent* StaticMeshComponent, int32 LODIndex, FMeshDescription& OutMeshDescription, bool bPropagateVertexColours)
{
RetrieveMeshInternal(StaticMeshComponent->GetStaticMesh(), StaticMeshComponent, LODIndex, OutMeshDescription, bPropagateVertexColours);
}
void FMeshMergeHelpers::RetrieveMesh(const UStaticMesh* StaticMesh, int32 LODIndex, FMeshDescription& OutMeshDescription)
{
RetrieveMeshInternal(StaticMesh, nullptr, LODIndex, OutMeshDescription, /*bPropagateVertexColours*/false);
}
void FMeshMergeHelpers::ExportStaticMeshLOD(const FStaticMeshLODResources& StaticMeshLOD, FMeshDescription& OutMeshDescription, const TArray<FStaticMaterial>& Materials)
{
const int32 NumWedges = StaticMeshLOD.IndexBuffer.GetNumIndices();
const int32 NumVertexPositions = StaticMeshLOD.VertexBuffers.PositionVertexBuffer.GetNumVertices();
const int32 NumFaces = NumWedges / 3;
OutMeshDescription.Empty();
if (NumVertexPositions <= 0 || StaticMeshLOD.VertexBuffers.StaticMeshVertexBuffer.GetNumVertices() <= 0)
{
return;
}
FStaticMeshAttributes Attributes(OutMeshDescription);
Attributes.Register();
TVertexAttributesRef<FVector3f> VertexPositions = Attributes.GetVertexPositions();
TEdgeAttributesRef<bool> EdgeHardnesses = Attributes.GetEdgeHardnesses();
TPolygonGroupAttributesRef<FName> PolygonGroupImportedMaterialSlotNames = Attributes.GetPolygonGroupMaterialSlotNames();
TVertexInstanceAttributesRef<FVector3f> VertexInstanceNormals = Attributes.GetVertexInstanceNormals();
TVertexInstanceAttributesRef<FVector3f> VertexInstanceTangents = Attributes.GetVertexInstanceTangents();
TVertexInstanceAttributesRef<float> VertexInstanceBinormalSigns = Attributes.GetVertexInstanceBinormalSigns();
TVertexInstanceAttributesRef<FVector4f> VertexInstanceColors = Attributes.GetVertexInstanceColors();
TVertexInstanceAttributesRef<FVector2f> VertexInstanceUVs = Attributes.GetVertexInstanceUVs();
OutMeshDescription.ReserveNewVertices(NumVertexPositions);
OutMeshDescription.ReserveNewVertexInstances(NumWedges);
OutMeshDescription.ReserveNewPolygons(NumFaces);
OutMeshDescription.ReserveNewEdges(NumWedges);
const int32 NumTexCoords = StaticMeshLOD.VertexBuffers.StaticMeshVertexBuffer.GetNumTexCoords();
First pass of MeshDescription API and format refactor. - Removed hardcoded element type arrays (Vertices, Edges, Triangles etc.). Mesh element types can now be arbitrarily added, with any number of channels. - Mesh element containers have a much leaner format; instead of sparse arrays, they are now represented by a simple bitarray, determining whether an index is used or not. Consequently, mesh topology is now entirely described with the attribute system, e.g. edge start and end vertices, triangle vertices, etc. - Support added for attributes of arbitrary dimensions, e.g. float[4] or int[2]. - Support added for attributes which index into another mesh element container. - Added FMeshElementIndexer: this is an efficient container for maintaining backward references from one element type to another; for example, edges have an attribute specifying which vertices are at each end (an attribute of type FVertexID[2]). With an indexer, it is possible to look up which edges contain a given vertex, even though this is not explicitly stored. Indexers are designed to do minimal allocations and update lazily and in batch when necessary. - Added support for preserving UV topology in static meshes. UVs are now a first-class element type which may be indexed directly from triangles. - Added the facility to access the underlying array in an attribute array directly. - Triangles now directly reference their vertex, edge and UV IDs. Vertex instances are to be deprecated. - Changed various systems to be triangle-centric rather than polygon-centric, as this is faster. Triangles are presumed to be the elementary face type in a MeshDescription, even if polygons are still supported. The concept of polygons will be somewhat shifted to mean a group of triangles which should be treated collectively for editing purposes. - Optimised normal/tangent generation and FBX import. - Deprecated EditableMesh, MeshEditor and StaticMeshEditorExtension plugins - these are to be removed, but they still have certain hooks in place which need removing. #rb [CL 13568702 by Richard TalbotWatkin in ue5-main branch]
2020-05-28 10:56:57 -04:00
VertexInstanceUVs.SetNumChannels(NumTexCoords);
for (int32 SectionIndex = 0; SectionIndex < StaticMeshLOD.Sections.Num(); ++SectionIndex)
{
const FStaticMeshSection& Section = StaticMeshLOD.Sections[SectionIndex];
FPolygonGroupID CurrentPolygonGroupID = OutMeshDescription.CreatePolygonGroup();
check(CurrentPolygonGroupID.GetValue() == SectionIndex);
if (Materials.IsValidIndex(Section.MaterialIndex))
{
PolygonGroupImportedMaterialSlotNames[CurrentPolygonGroupID] = Materials[Section.MaterialIndex].ImportedMaterialSlotName;
}
else
{
PolygonGroupImportedMaterialSlotNames[CurrentPolygonGroupID] = FName(*(TEXT("MeshMergeMaterial_") + FString::FromInt(SectionIndex)));
}
}
//Create the vertex
for (int32 VertexIndex = 0; VertexIndex < NumVertexPositions; ++VertexIndex)
{
FVertexID VertexID = OutMeshDescription.CreateVertex();
VertexPositions[VertexID] = StaticMeshLOD.VertexBuffers.PositionVertexBuffer.VertexPosition(VertexIndex);
}
//Create the vertex instances
for (int32 TriangleIndex = 0; TriangleIndex < NumFaces; ++TriangleIndex)
{
First pass of MeshDescription API and format refactor. - Removed hardcoded element type arrays (Vertices, Edges, Triangles etc.). Mesh element types can now be arbitrarily added, with any number of channels. - Mesh element containers have a much leaner format; instead of sparse arrays, they are now represented by a simple bitarray, determining whether an index is used or not. Consequently, mesh topology is now entirely described with the attribute system, e.g. edge start and end vertices, triangle vertices, etc. - Support added for attributes of arbitrary dimensions, e.g. float[4] or int[2]. - Support added for attributes which index into another mesh element container. - Added FMeshElementIndexer: this is an efficient container for maintaining backward references from one element type to another; for example, edges have an attribute specifying which vertices are at each end (an attribute of type FVertexID[2]). With an indexer, it is possible to look up which edges contain a given vertex, even though this is not explicitly stored. Indexers are designed to do minimal allocations and update lazily and in batch when necessary. - Added support for preserving UV topology in static meshes. UVs are now a first-class element type which may be indexed directly from triangles. - Added the facility to access the underlying array in an attribute array directly. - Triangles now directly reference their vertex, edge and UV IDs. Vertex instances are to be deprecated. - Changed various systems to be triangle-centric rather than polygon-centric, as this is faster. Triangles are presumed to be the elementary face type in a MeshDescription, even if polygons are still supported. The concept of polygons will be somewhat shifted to mean a group of triangles which should be treated collectively for editing purposes. - Optimised normal/tangent generation and FBX import. - Deprecated EditableMesh, MeshEditor and StaticMeshEditorExtension plugins - these are to be removed, but they still have certain hooks in place which need removing. #rb [CL 13568702 by Richard TalbotWatkin in ue5-main branch]
2020-05-28 10:56:57 -04:00
FPolygonGroupID CurrentPolygonGroupID = INDEX_NONE;
for (int32 SectionIndex = 0; SectionIndex < StaticMeshLOD.Sections.Num(); ++SectionIndex)
{
const FStaticMeshSection& Section = StaticMeshLOD.Sections[SectionIndex];
uint32 BeginTriangle = Section.FirstIndex / 3;
uint32 EndTriangle = BeginTriangle + Section.NumTriangles;
if ((uint32)TriangleIndex >= BeginTriangle && (uint32)TriangleIndex < EndTriangle)
{
CurrentPolygonGroupID = FPolygonGroupID(SectionIndex);
break;
}
}
First pass of MeshDescription API and format refactor. - Removed hardcoded element type arrays (Vertices, Edges, Triangles etc.). Mesh element types can now be arbitrarily added, with any number of channels. - Mesh element containers have a much leaner format; instead of sparse arrays, they are now represented by a simple bitarray, determining whether an index is used or not. Consequently, mesh topology is now entirely described with the attribute system, e.g. edge start and end vertices, triangle vertices, etc. - Support added for attributes of arbitrary dimensions, e.g. float[4] or int[2]. - Support added for attributes which index into another mesh element container. - Added FMeshElementIndexer: this is an efficient container for maintaining backward references from one element type to another; for example, edges have an attribute specifying which vertices are at each end (an attribute of type FVertexID[2]). With an indexer, it is possible to look up which edges contain a given vertex, even though this is not explicitly stored. Indexers are designed to do minimal allocations and update lazily and in batch when necessary. - Added support for preserving UV topology in static meshes. UVs are now a first-class element type which may be indexed directly from triangles. - Added the facility to access the underlying array in an attribute array directly. - Triangles now directly reference their vertex, edge and UV IDs. Vertex instances are to be deprecated. - Changed various systems to be triangle-centric rather than polygon-centric, as this is faster. Triangles are presumed to be the elementary face type in a MeshDescription, even if polygons are still supported. The concept of polygons will be somewhat shifted to mean a group of triangles which should be treated collectively for editing purposes. - Optimised normal/tangent generation and FBX import. - Deprecated EditableMesh, MeshEditor and StaticMeshEditorExtension plugins - these are to be removed, but they still have certain hooks in place which need removing. #rb [CL 13568702 by Richard TalbotWatkin in ue5-main branch]
2020-05-28 10:56:57 -04:00
check(CurrentPolygonGroupID != INDEX_NONE);
FVertexID VertexIDs[3];
TArray<FVertexInstanceID> VertexInstanceIDs;
VertexInstanceIDs.SetNum(3);
for (int32 Corner = 0; Corner < 3; ++Corner)
{
int32 WedgeIndex = StaticMeshLOD.IndexBuffer.GetIndex(TriangleIndex * 3 + Corner);
FVertexID VertexID(WedgeIndex);
FVertexInstanceID VertexInstanceID = OutMeshDescription.CreateVertexInstance(VertexID);
VertexIDs[Corner] = VertexID;
VertexInstanceIDs[Corner] = VertexInstanceID;
//NTBs
FVector TangentX = FVector4(StaticMeshLOD.VertexBuffers.StaticMeshVertexBuffer.VertexTangentX(WedgeIndex));
FVector TangentY = FVector(StaticMeshLOD.VertexBuffers.StaticMeshVertexBuffer.VertexTangentY(WedgeIndex));
FVector TangentZ = FVector4(StaticMeshLOD.VertexBuffers.StaticMeshVertexBuffer.VertexTangentZ(WedgeIndex));
VertexInstanceTangents[VertexInstanceID] = (FVector3f)TangentX;
VertexInstanceBinormalSigns[VertexInstanceID] = GetBasisDeterminantSign(TangentX, TangentY, TangentZ);
VertexInstanceNormals[VertexInstanceID] = (FVector3f)TangentZ;
// Vertex colors
if (StaticMeshLOD.VertexBuffers.ColorVertexBuffer.GetNumVertices() > 0)
{
VertexInstanceColors[VertexInstanceID] = FLinearColor(StaticMeshLOD.VertexBuffers.ColorVertexBuffer.VertexColor(WedgeIndex));
}
else
{
VertexInstanceColors[VertexInstanceID] = FLinearColor::White;
}
//Tex coord
for (int32 TexCoodIdx = 0; TexCoodIdx < NumTexCoords; ++TexCoodIdx)
{
VertexInstanceUVs.Set(VertexInstanceID, TexCoodIdx, StaticMeshLOD.VertexBuffers.StaticMeshVertexBuffer.GetVertexUV(WedgeIndex, TexCoodIdx));
}
}
//Create a polygon from this triangle
const FPolygonID NewPolygonID = OutMeshDescription.CreatePolygon(CurrentPolygonGroupID, VertexInstanceIDs);
}
}
void FMeshMergeHelpers::RetrieveMesh(const USkeletalMeshComponent* SkeletalMeshComponent, int32 LODIndex, FMeshDescription& OutMeshDescription, bool bPropagateVertexColours)
{
FSkeletalMeshModel* Resource = SkeletalMeshComponent->SkeletalMesh->GetImportedModel();
if (Resource->LODModels.IsValidIndex(LODIndex))
{
FSkeletalMeshLODInfo& SrcLODInfo = *(SkeletalMeshComponent->SkeletalMesh->GetLODInfo(LODIndex));
// Get the CPU skinned verts for this LOD
TArray<FFinalSkinVertex> FinalVertices;
// GetCPUSkinnedVertices
SkeletalMeshComponent->GetCPUSkinnedVertices(FinalVertices, LODIndex);
FSkeletalMeshLODModel& LODModel = Resource->LODModels[LODIndex];
const int32 NumSections = LODModel.Sections.Num();
// Empty the mesh description
OutMeshDescription.Empty();
FStaticMeshAttributes Attributes(OutMeshDescription);
TVertexAttributesRef<FVector3f> VertexPositions = Attributes.GetVertexPositions();
TEdgeAttributesRef<bool> EdgeHardnesses = Attributes.GetEdgeHardnesses();
TPolygonGroupAttributesRef<FName> PolygonGroupImportedMaterialSlotNames = Attributes.GetPolygonGroupMaterialSlotNames();
TVertexInstanceAttributesRef<FVector3f> VertexInstanceNormals = Attributes.GetVertexInstanceNormals();
TVertexInstanceAttributesRef<FVector3f> VertexInstanceTangents = Attributes.GetVertexInstanceTangents();
TVertexInstanceAttributesRef<float> VertexInstanceBinormalSigns = Attributes.GetVertexInstanceBinormalSigns();
TVertexInstanceAttributesRef<FVector4f> VertexInstanceColors = Attributes.GetVertexInstanceColors();
TVertexInstanceAttributesRef<FVector2f> VertexInstanceUVs = Attributes.GetVertexInstanceUVs();
int32 TotalTriangles = 0;
int32 TotalCorners = 0;
for (int32 SectionIndex = 0; SectionIndex < NumSections; SectionIndex++)
{
const FSkelMeshSection& SkelMeshSection = LODModel.Sections[SectionIndex];
TotalTriangles += SkelMeshSection.NumTriangles;
}
TotalCorners = TotalTriangles * 3;
OutMeshDescription.ReserveNewVertices(FinalVertices.Num());
OutMeshDescription.ReserveNewPolygons(TotalTriangles);
OutMeshDescription.ReserveNewVertexInstances(TotalCorners);
OutMeshDescription.ReserveNewEdges(TotalCorners);
// Copy skinned vertex positions
for (int32 VertIndex = 0; VertIndex < FinalVertices.Num(); ++VertIndex)
{
const FVertexID VertexID = OutMeshDescription.CreateVertex();
VertexPositions[VertexID] = FinalVertices[VertIndex].Position;
}
VertexInstanceUVs.SetNumChannels(MAX_TEXCOORDS);
for (int32 SectionIndex = 0; SectionIndex < NumSections; SectionIndex++)
{
const FSkelMeshSection& SkelMeshSection = LODModel.Sections[SectionIndex];
const int32 NumWedges = SkelMeshSection.NumTriangles * 3;
//Create the polygon group ID
int32 MaterialIndex = SkelMeshSection.MaterialIndex;
// use the remapping of material indices if there is a valid value
if (SrcLODInfo.LODMaterialMap.IsValidIndex(SectionIndex) && SrcLODInfo.LODMaterialMap[SectionIndex] != INDEX_NONE)
{
MaterialIndex = FMath::Clamp<int32>(SrcLODInfo.LODMaterialMap[SectionIndex], 0, SkeletalMeshComponent->SkeletalMesh->GetMaterials().Num() - 1);
}
FName ImportedMaterialSlotName = SkeletalMeshComponent->SkeletalMesh->GetMaterials()[MaterialIndex].ImportedMaterialSlotName;
const FPolygonGroupID SectionPolygonGroupID(SectionIndex);
if (!OutMeshDescription.IsPolygonGroupValid(SectionPolygonGroupID))
{
OutMeshDescription.CreatePolygonGroupWithID(SectionPolygonGroupID);
PolygonGroupImportedMaterialSlotNames[SectionPolygonGroupID] = ImportedMaterialSlotName;
}
int32 WedgeIndex = 0;
for (uint32 SectionTriangleIndex = 0; SectionTriangleIndex < SkelMeshSection.NumTriangles; ++SectionTriangleIndex)
{
FVertexID VertexIndexes[3];
TArray<FVertexInstanceID> VertexInstanceIDs;
VertexInstanceIDs.SetNum(3);
for (int32 CornerIndex = 0; CornerIndex < 3; ++CornerIndex, ++WedgeIndex)
{
const int32 VertexIndexForWedge = LODModel.IndexBuffer[SkelMeshSection.BaseIndex + WedgeIndex];
VertexIndexes[CornerIndex] = FVertexID(VertexIndexForWedge);
FVertexInstanceID VertexInstanceID = OutMeshDescription.CreateVertexInstance(VertexIndexes[CornerIndex]);
VertexInstanceIDs[CornerIndex] = VertexInstanceID;
const FSoftSkinVertex& SoftVertex = SkelMeshSection.SoftVertices[VertexIndexForWedge - SkelMeshSection.BaseVertexIndex];
const FFinalSkinVertex& SkinnedVertex = FinalVertices[VertexIndexForWedge];
//Set NTBs
const FVector TangentX = SkinnedVertex.TangentX.ToFVector();
const FVector TangentZ = SkinnedVertex.TangentZ.ToFVector();
//@todo: do we need to inverse the sign between skeletalmesh and staticmesh, the old code was doing so.
const float TangentYSign = SkinnedVertex.TangentZ.ToFVector4f().W;
VertexInstanceTangents[VertexInstanceID] = (FVector3f)TangentX;
VertexInstanceBinormalSigns[VertexInstanceID] = TangentYSign;
VertexInstanceNormals[VertexInstanceID] = (FVector3f)TangentZ;
for (uint32 TexCoordIndex = 0; TexCoordIndex < MAX_TEXCOORDS; TexCoordIndex++)
{
//Add this vertex instance tex coord
VertexInstanceUVs.Set(VertexInstanceID, TexCoordIndex, SoftVertex.UVs[TexCoordIndex]);
}
//Add this vertex instance color
VertexInstanceColors[VertexInstanceID] = bPropagateVertexColours ? FVector4f(FLinearColor(SoftVertex.Color)) : FVector4f(1.0f, 1.0f, 1.0f);
}
//Create a polygon from this triangle
const FPolygonID NewPolygonID = OutMeshDescription.CreatePolygon(SectionPolygonGroupID, VertexInstanceIDs);
}
}
}
}
bool FMeshMergeHelpers::CheckWrappingUVs(const TArray<FVector2D>& UVs)
{
bool bResult = false;
FVector2D Min(FLT_MAX, FLT_MAX);
FVector2D Max(-FLT_MAX, -FLT_MAX);
for (const FVector2D& Coordinate : UVs)
{
if ((Coordinate.X < 0.0f || Coordinate.Y < 0.0f) || (Coordinate.X > (1.0f + KINDA_SMALL_NUMBER) || Coordinate.Y > (1.0f + KINDA_SMALL_NUMBER)))
{
bResult = true;
break;
}
}
return bResult;
}
bool FMeshMergeHelpers::CheckWrappingUVs(const FMeshDescription& MeshDescription, int32 UVChannelIndex)
{
TVertexInstanceAttributesConstRef<FVector2f> VertexInstanceUVs = FStaticMeshConstAttributes(MeshDescription).GetVertexInstanceUVs();
bool bResult = false;
//Validate the channel, return false if there is an invalid channel index
First pass of MeshDescription API and format refactor. - Removed hardcoded element type arrays (Vertices, Edges, Triangles etc.). Mesh element types can now be arbitrarily added, with any number of channels. - Mesh element containers have a much leaner format; instead of sparse arrays, they are now represented by a simple bitarray, determining whether an index is used or not. Consequently, mesh topology is now entirely described with the attribute system, e.g. edge start and end vertices, triangle vertices, etc. - Support added for attributes of arbitrary dimensions, e.g. float[4] or int[2]. - Support added for attributes which index into another mesh element container. - Added FMeshElementIndexer: this is an efficient container for maintaining backward references from one element type to another; for example, edges have an attribute specifying which vertices are at each end (an attribute of type FVertexID[2]). With an indexer, it is possible to look up which edges contain a given vertex, even though this is not explicitly stored. Indexers are designed to do minimal allocations and update lazily and in batch when necessary. - Added support for preserving UV topology in static meshes. UVs are now a first-class element type which may be indexed directly from triangles. - Added the facility to access the underlying array in an attribute array directly. - Triangles now directly reference their vertex, edge and UV IDs. Vertex instances are to be deprecated. - Changed various systems to be triangle-centric rather than polygon-centric, as this is faster. Triangles are presumed to be the elementary face type in a MeshDescription, even if polygons are still supported. The concept of polygons will be somewhat shifted to mean a group of triangles which should be treated collectively for editing purposes. - Optimised normal/tangent generation and FBX import. - Deprecated EditableMesh, MeshEditor and StaticMeshEditorExtension plugins - these are to be removed, but they still have certain hooks in place which need removing. #rb [CL 13568702 by Richard TalbotWatkin in ue5-main branch]
2020-05-28 10:56:57 -04:00
if (UVChannelIndex < 0 || UVChannelIndex >= VertexInstanceUVs.GetNumChannels())
{
return bResult;
}
for (const FVertexInstanceID VertexInstanceID : MeshDescription.VertexInstances().GetElementIDs())
{
const FVector2D& Coordinate = FVector2D(VertexInstanceUVs.Get(VertexInstanceID, UVChannelIndex));
if ((Coordinate.X < 0.0f || Coordinate.Y < 0.0f) || (Coordinate.X > (1.0f + KINDA_SMALL_NUMBER) || Coordinate.Y > (1.0f + KINDA_SMALL_NUMBER)))
{
bResult = true;
break;
}
}
return bResult;
}
void FMeshMergeHelpers::CullTrianglesFromVolumesAndUnderLandscapes(const UWorld* World, const FBoxSphereBounds& Bounds, FMeshDescription& InOutMeshDescription)
{
TArray<ALandscapeProxy*> Landscapes;
TArray<AMeshMergeCullingVolume*> CullVolumes;
FBox BoxBounds = Bounds.GetBox();
for (ULevel* Level : World->GetLevels())
{
for (AActor* Actor : Level->Actors)
{
ALandscapeProxy* LandscapeProxy = Cast<ALandscapeProxy>(Actor);
if (LandscapeProxy && LandscapeProxy->bUseLandscapeForCullingInvisibleHLODVertices)
{
FVector Origin, Extent;
LandscapeProxy->GetActorBounds(false, Origin, Extent);
FBox LandscapeBox(Origin - Extent, Origin + Extent);
// Ignore Z axis for 2d bounds check
if (LandscapeBox.IntersectXY(BoxBounds))
{
Landscapes.Add(LandscapeProxy);
}
}
// Check for culling volumes
AMeshMergeCullingVolume* Volume = Cast<AMeshMergeCullingVolume>(Actor);
if (Volume)
{
// If the mesh's bounds intersect with the volume there is a possibility of culling
const bool bIntersecting = Volume->EncompassesPoint(Bounds.Origin, Bounds.SphereRadius, nullptr);
if (bIntersecting)
{
CullVolumes.Add(Volume);
}
}
}
}
TVertexAttributesConstRef<FVector3f> VertexPositions = InOutMeshDescription.GetVertexPositions();
TMap<FVertexID, bool> VertexVisible;
VertexVisible.Reserve(InOutMeshDescription.Vertices().Num());
int32 Index = 0;
for(const FVertexID VertexID : InOutMeshDescription.Vertices().GetElementIDs())
{
const FVector3f& Position = VertexPositions[VertexID];
// Start with setting visibility to true on all vertices
VertexVisible.Add(VertexID, true);
// Check if this vertex is culled due to being underneath a landscape
if (Landscapes.Num() > 0)
{
bool bVertexWithinLandscapeBounds = false;
for (ALandscapeProxy* Proxy : Landscapes)
{
FVector Origin, Extent;
Proxy->GetActorBounds(false, Origin, Extent);
FBox LandscapeBox(Origin - Extent, Origin + Extent);
bVertexWithinLandscapeBounds |= LandscapeBox.IsInsideXY((FVector)Position);
}
if (bVertexWithinLandscapeBounds)
{
const FVector Start = (FVector)Position;
FVector End = (FVector)Position - (WORLD_MAX * FVector::UpVector);
FVector OutHit;
const bool IsAboveLandscape = IsLandscapeHit(Start, End, World, Landscapes, OutHit);
End = (FVector)Position + (WORLD_MAX * FVector::UpVector);
const bool IsUnderneathLandscape = IsLandscapeHit(Start, End, World, Landscapes, OutHit);
// Vertex is visible when above landscape (with actual landscape underneath) or if there is no landscape beneath or above the vertex (falls outside of landscape bounds)
VertexVisible[VertexID] = (IsAboveLandscape && !IsUnderneathLandscape);// || (!IsAboveLandscape && !IsUnderneathLandscape);
}
}
// Volume culling
for (AMeshMergeCullingVolume* Volume : CullVolumes)
{
const bool bVertexIsInsideVolume = Volume->EncompassesPoint((FVector)Position, 0.0f, nullptr);
if (bVertexIsInsideVolume)
{
// Inside a culling volume so invisible
VertexVisible[VertexID] = false;
}
}
Index++;
}
// We now know which vertices are below the landscape
TArray<FTriangleID> TriangleToRemove;
for(const FTriangleID TriangleID : InOutMeshDescription.Triangles().GetElementIDs())
{
bool AboveLandscape = false;
for (int32 Corner = 0; Corner < 3; ++Corner)
{
AboveLandscape |= VertexVisible[InOutMeshDescription.GetVertexInstanceVertex(InOutMeshDescription.GetTriangleVertexInstance(TriangleID, Corner))];
}
if (!AboveLandscape)
{
TriangleToRemove.Add(TriangleID);
}
}
// Delete the polygons that are not visible
{
TArray<FEdgeID> OrphanedEdges;
TArray<FVertexInstanceID> OrphanedVertexInstances;
TArray<FPolygonGroupID> OrphanedPolygonGroups;
TArray<FVertexID> OrphanedVertices;
for (FTriangleID TriangleID : TriangleToRemove)
{
InOutMeshDescription.DeleteTriangle(TriangleID, &OrphanedEdges, &OrphanedVertexInstances, &OrphanedPolygonGroups);
}
//Do not remove the polygongroup since its indexed with the mesh material array
/*for (FPolygonGroupID PolygonGroupID : OrphanedPolygonGroups)
{
InOutRawMesh.DeletePolygonGroup(PolygonGroupID);
}*/
for (FVertexInstanceID VertexInstanceID : OrphanedVertexInstances)
{
InOutMeshDescription.DeleteVertexInstance(VertexInstanceID, &OrphanedVertices);
}
for (FEdgeID EdgeID : OrphanedEdges)
{
InOutMeshDescription.DeleteEdge(EdgeID, &OrphanedVertices);
}
for (FVertexID VertexID : OrphanedVertices)
{
InOutMeshDescription.DeleteVertex(VertexID);
}
//Compact and Remap IDs so we have clean ID from 0 to n since we just erase some polygons
//The render build need to have compact ID
FElementIDRemappings OutRemappings;
InOutMeshDescription.Compact(OutRemappings);
}
}
void FMeshMergeHelpers::PropagateSplineDeformationToMesh(const USplineMeshComponent* InSplineMeshComponent, FMeshDescription& InOutMeshDescription)
{
FStaticMeshAttributes Attributes(InOutMeshDescription);
TVertexAttributesRef<FVector3f> VertexPositions = Attributes.GetVertexPositions();
TVertexInstanceAttributesRef<FVector3f> VertexInstanceNormals = Attributes.GetVertexInstanceNormals();
TVertexInstanceAttributesRef<FVector3f> VertexInstanceTangents = Attributes.GetVertexInstanceTangents();
TVertexInstanceAttributesRef<float> VertexInstanceBinormalSigns = Attributes.GetVertexInstanceBinormalSigns();
// Apply spline deformation for each vertex's tangents
int32 WedgeIndex = 0;
for (const FTriangleID TriangleID : InOutMeshDescription.Triangles().GetElementIDs())
{
for (int32 Corner = 0; Corner < 3; ++Corner, ++WedgeIndex)
{
const FVertexInstanceID VertexInstanceID = InOutMeshDescription.GetTriangleVertexInstance(TriangleID, Corner);
const FVertexID VertexID = InOutMeshDescription.GetVertexInstanceVertex(VertexInstanceID);
const float& AxisValue = USplineMeshComponent::GetAxisValue(VertexPositions[VertexID], InSplineMeshComponent->ForwardAxis);
FTransform SliceTransform = InSplineMeshComponent->CalcSliceTransform(AxisValue);
FVector TangentY = FVector::CrossProduct((FVector)VertexInstanceNormals[VertexInstanceID], (FVector)VertexInstanceTangents[VertexInstanceID]).GetSafeNormal() * VertexInstanceBinormalSigns[VertexInstanceID];
VertexInstanceTangents[VertexInstanceID] = (FVector3f)SliceTransform.TransformVector((FVector)VertexInstanceTangents[VertexInstanceID]);
TangentY = SliceTransform.TransformVector(TangentY);
VertexInstanceNormals[VertexInstanceID] = (FVector3f)SliceTransform.TransformVector((FVector)VertexInstanceNormals[VertexInstanceID]);
VertexInstanceBinormalSigns[VertexInstanceID] = GetBasisDeterminantSign((FVector)VertexInstanceTangents[VertexInstanceID], TangentY, (FVector)VertexInstanceNormals[VertexInstanceID]);
}
}
// Apply spline deformation for each vertex position
for (const FVertexID VertexID : InOutMeshDescription.Vertices().GetElementIDs())
{
float& AxisValue = USplineMeshComponent::GetAxisValue(VertexPositions[VertexID], InSplineMeshComponent->ForwardAxis);
FTransform SliceTransform = InSplineMeshComponent->CalcSliceTransform(AxisValue);
AxisValue = 0.0f;
VertexPositions[VertexID] = (FVector3f)SliceTransform.TransformPosition((FVector)VertexPositions[VertexID]);
}
}
void FMeshMergeHelpers::PropagateSplineDeformationToPhysicsGeometry(USplineMeshComponent* SplineMeshComponent, FKAggregateGeom& InOutPhysicsGeometry)
{
const FVector Mask = USplineMeshComponent::GetAxisMask(SplineMeshComponent->GetForwardAxis());
for (FKConvexElem& Elem : InOutPhysicsGeometry.ConvexElems)
{
for (FVector& Position : Elem.VertexData)
{
const float& AxisValue = USplineMeshComponent::GetAxisValue(Position, SplineMeshComponent->ForwardAxis);
FTransform SliceTransform = SplineMeshComponent->CalcSliceTransform(AxisValue);
Position = SliceTransform.TransformPosition(Position * Mask);
}
Elem.UpdateElemBox();
}
for (FKSphereElem& Elem : InOutPhysicsGeometry.SphereElems)
{
const FVector WorldSpaceCenter = Elem.GetTransform().TransformPosition(Elem.Center);
Elem.Center = SplineMeshComponent->CalcSliceTransform(USplineMeshComponent::GetAxisValue(WorldSpaceCenter, SplineMeshComponent->ForwardAxis)).TransformPosition(Elem.Center * Mask);
}
for (FKSphylElem& Elem : InOutPhysicsGeometry.SphylElems)
{
const FVector WorldSpaceCenter = Elem.GetTransform().TransformPosition(Elem.Center);
Elem.Center = SplineMeshComponent->CalcSliceTransform(USplineMeshComponent::GetAxisValue(WorldSpaceCenter, SplineMeshComponent->ForwardAxis)).TransformPosition(Elem.Center * Mask);
}
}
void FMeshMergeHelpers::RetrieveCullingLandscapeAndVolumes(UWorld* InWorld, const FBoxSphereBounds& EstimatedMeshProxyBounds, const TEnumAsByte<ELandscapeCullingPrecision::Type> PrecisionType, TArray<FMeshDescription*>& OutCullingMeshes)
{
// Extract landscape proxies and cull volumes from the world
TArray<ALandscapeProxy*> LandscapeActors;
TArray<AMeshMergeCullingVolume*> CullVolumes;
uint32 MaxLandscapeExportLOD = 0;
if (InWorld->IsValidLowLevel())
{
for (FConstLevelIterator Iterator = InWorld->GetLevelIterator(); Iterator; ++Iterator)
{
for (AActor* Actor : (*Iterator)->Actors)
{
if (Actor)
{
ALandscapeProxy* LandscapeProxy = Cast<ALandscapeProxy>(Actor);
if (LandscapeProxy && LandscapeProxy->bUseLandscapeForCullingInvisibleHLODVertices)
{
// Retrieve highest landscape LOD level possible
MaxLandscapeExportLOD = FMath::Max(MaxLandscapeExportLOD, FMath::CeilLogTwo(LandscapeProxy->SubsectionSizeQuads + 1) - 1);
LandscapeActors.Add(LandscapeProxy);
}
// Check for culling volumes
AMeshMergeCullingVolume* Volume = Cast<AMeshMergeCullingVolume>(Actor);
if (Volume)
{
// If the mesh's bounds intersect with the volume there is a possibility of culling
const bool bIntersecting = Volume->EncompassesPoint(EstimatedMeshProxyBounds.Origin, EstimatedMeshProxyBounds.SphereRadius, nullptr);
if (bIntersecting)
{
CullVolumes.Add(Volume);
}
}
}
}
}
}
// Setting determines the precision at which we should export the landscape for culling (highest, half or lowest)
const uint32 LandscapeExportLOD = ((float)MaxLandscapeExportLOD * (0.5f * (float)PrecisionType));
for (ALandscapeProxy* Landscape : LandscapeActors)
{
// Export the landscape to raw mesh format
FMeshDescription* MeshDescription = new FMeshDescription();
FStaticMeshAttributes(*MeshDescription).Register();
FBoxSphereBounds LandscapeBounds = EstimatedMeshProxyBounds;
Landscape->ExportToRawMesh(LandscapeExportLOD, *MeshDescription, LandscapeBounds);
if (MeshDescription->Vertices().Num())
{
OutCullingMeshes.Add(MeshDescription);
}
}
// Also add volume mesh data as culling meshes
for (AMeshMergeCullingVolume* Volume : CullVolumes)
{
// Export the landscape to raw mesh format
FMeshDescription* VolumeMesh = new FMeshDescription();
FStaticMeshAttributes MeshAttributes(*VolumeMesh);
MeshAttributes.Register();
TArray<FStaticMaterial> VolumeMaterials;
GetBrushMesh(Volume, Volume->Brush, *VolumeMesh, VolumeMaterials);
// Offset vertices to correct world position;
FVector VolumeLocation = Volume->GetActorLocation();
TVertexAttributesRef<FVector3f> VertexPositions = MeshAttributes.GetVertexPositions();
for(const FVertexID VertexID : VolumeMesh->Vertices().GetElementIDs())
{
VertexPositions[VertexID] += (FVector3f)VolumeLocation;
}
OutCullingMeshes.Add(VolumeMesh);
}
}
Copying //UE4/Dev-Physics to //UE4/Dev-Main (Source: //UE4/Dev-Physics @ 4242698) #rb none #lockdown Nick.Penwarden ============================ MAJOR FEATURES & CHANGES ============================ Change 4023283 by Michael.Lentine Fix memory leak. Change 4024243 by Michael.Lentine Add debugging output code from github #4533. #jira ue-55764 Change 4026362 by Michael.Lentine Merged github #3704. #jira ue-463394 Change 4026545 by Michael.Lentine Fix ordering of collision settings changed callback #jira ue-50475 Change 4026609 by Michael.Lentine Fix crash in destruction for when world is not valid #jira ue-53989 Change 4026786 by Michael.Lentine Merging github #4632 to fix memory leak. #jira ue-57255 Change 4027293 by Michael.Lentine Integrate github #4338. #jira ue-53497 Change 4033517 by Michael.Lentine Fix collision body creation for spline merging. #jira ue-53956 Change 4039750 by Michael.Lentine Add basic error message if cooking fails. Change 4040210 by Michael.Lentine Check for nullptr Change 4098887 by Michael.Lentine Fix warnings. Change 4103511 by Michael.Lentine Prevent crash when BodyInstance is invalid. Change 4117826 by Michael.Lentine Fix check for body being fixed. Change 4122307 by Benn.Gallagher PS4/clang build fixes Change 4124479 by Benn.Gallagher Fix non-portable filename used as an include (Linux editor build CIS error) Change 4125450 by Benn.Gallagher Fixup Ocean Change 4127210 by Michael.Lentine Update the PreviousBoneTransforms array when setting transforms in DestructibleComponent #jira ue-58813 Change 4127309 by Benn.Gallagher Fix Win32 shipping builds Change 4134570 by Michael.Lentine Missed fixes for WITH_UEPHYSICS. Change 4134585 by Michael.Lentine Missed a few more files. Change 4134670 by Michael.Lentine Update formatting. Change 4134671 by Michael.Lentine More formatting. Change 4150615 by Benn.Gallagher Moved immediate mode into engine, as it is now depended on by the physics engine. Change 4150680 by Benn.Gallagher Missed file Change 4150980 by Benn.Gallagher Rename kinematic target for immediate mode to avoid ambiguous symbols in engine Change 4151400 by Brice.Criswell Apeiron Levelset initilization issue. ---- Change 4157880 by Benn.Gallagher More fixing unresolved template specialisations for FN editor. Change 4159128 by Michael.Lentine Compile fixes Change 4159786 by Brice.Criswell Apeiron Levelset curvature initialization fix, clamps out of bounds phi values to phi[i]. ------ Change 4160382 by Michael.Lentine Fix node initialization Change 4160463 by Brice.Criswell Apeiron Levelset index fix. ---- Change 4161425 by Benn.Gallagher Added package, class and struct redirects for moving immediate physics into engine. Change 4164195 by Brice.Criswell GeometryCollection : Code review updates - Removed typedef for GeometryCollection::ManagedArray<T> - Renamed Enumerations to begin with E prefix, retyped to be uint8. - Removed EArrayScoipe::FScopeNone, now defautls to FScopeShared - Formatted type modifiers to follow UE4 coding standard. - Derived the ManagedArrayBase from FNonCopyable - Disabled TManagedArrays copy constructor and assignment operator. - Converted most accessors on GeometryCollection to TSharedRef. - Added .inl style definitions to simplify the management of the ManagedArrayTypes ----- Change 4164235 by Brice.Criswell GeometryCollection : Added New Files - Added the ManagedArrayTypes files. ---- Change 4164309 by Brice.Criswell GeometryCollection : Moved the initialization of the RigidBodyIdArray and CenterOfMassArray into the WITH_APEIRON definition. ----- Change 4166133 by Brice.Criswell GeometryCollection Added GeometryCollectionEdit class to protect access to the rest and dynamic collections. ----- Change 4171540 by Michael.Lentine Fix reset #robomerge destruction Change 4171912 by Michael.Lentine Rename BVHParticles #robomerge destruction Change 4172445 by Brice.Criswell Copying //UE4/Dev-Destruction to Dev-Physics (//UE4/Dev-Physics) ---- Change 4172623 by Brice.Criswell GeometryCollection Debugging ToString to inspect the GeometryCollection ---- Change 4172711 by Michael.Lentine Add Immediate Path to Geometry Collection Change 4172778 by Michael.Lentine Update LL Interface to use Simulation type. #robomerge destruction Change 4172780 by Michael.Lentine Missed files #robomerge destruction Change 4173238 by Benn.Gallagher Missed file from last checkin Change 4173554 by Benn.Gallagher Few extra changes for const correctness and actor counts Change 4174153 by Benn.Gallagher Fixed non-unity build issue from Geom Collection. Change 4175355 by Brice.Criswell GeometryCollection Separated the GeometryCollection from USE_APEIRON flag. ----- Change 4175533 by Brice.Criswell GeometryCollection Defaulting Aperion to off. ----- Change 4175761 by Michael.Lentine Fix collisions. Change 4177105 by Benn.Gallagher Another geom collection CIS fix when running without PCHs Change 4177796 by Brice.Criswell GeometryCollection - Added parenting function to manage the BoneHierarchy Array - Split collection along yz-plane. ----- Change 4177989 by Brice.Criswell GeometryCollection - Moved Hierarchy and Transform array elements into base class TransformCollection - Renamed ParticleGroup to TransformGroup. ----- Change 4178826 by Brice.Criswell Copying //UE4/Dev-Destruction to Dev-Physics (//UE4/Dev-Physics) ---- Change 4178840 by Brice.Criswell Geometry Collection Removed FORCEINLINE from GeometryCollectionEdit.GetRestCollection ---- Change 4179493 by Brice.Criswell GeometryCollection New icons. ----- Change 4182428 by Brice.Criswell Build Configuration Apeiron configuration. - Modified bCompileApeiron to enable the compilation of the Apeiron plugin. - Added bUseApeiron to enable Apeiron in the physics interfaces. Changed PhysScene_Apeiron to enable when bCompileApeiron is enabled. Disabled the GeometryCollection* Plugins in the build. ------- Change 4185886 by Brice.Criswell GeometryCollection Renaming TransformGroup. --- Change 4186389 by michael.lentine Don't create in parallel for immediate mode. Change 4186457 by michael.lentine Hack to prevent crashing when Visible is nullptr. Change 4198872 by Brice.Criswell Apeiron Clustering changes - Clustering based on hierarchy's defined within the Geometry Collection ----- Change 4199861 by Brice.Criswell GeometryCollection Disable Apeiron in the Collection. ------ Change 4200089 by Brice.Criswell GeometryCollection Updated to enable Apeiron in the GeometryCollection when the bCompileAperion flag is enabled in the UnrealBuildTool. --- Change 4200333 by Brice.Criswell Copying //UE4/Dev-Destruction to Dev-Physics (//UE4/Dev-Physics) ----- Change 4202231 by Michael.Lentine Disable collisions between adjacent bodies connected by a joint. This typically would be specified by an artist but classic PhysX always does this uncondintionally so our clients are used to this. Change 4202748 by Michael.Lentine Fix 2015 compile. Change 4204528 by Michael.Lentine Disable Apeiron. Change 4206396 by Michael.Lentine Fix 2015 build. Static cast apparently is not an accetible conversion from uint32 to bool. #robomerge destruction Change 4206604 by Michael.Lentine Fix for using ccd and kinematic. #jira UE-61694 #robomerge destruction Change 4206711 by mason.seay Refreshed Set Angular Drive nodes to clear out orphan pins Change 4207286 by Brice.Criswell GeometryCollection Transform hierarchy evaluation within BoneHierarchy of the Collection. Parenting operations are implemented on an updated morphology using : ParentTransforms(UGeometryCollection* GeometryCollection, const int32 InsertAtIndex, const TArray<int32>& SelectedBones); To parent a new transform: int32 RootIndex << within len( TransformGroup ) or -1 for a non-parented node. int32 BoneIndex = Collection->AddElements(1, UGeometryCollection::TransformGroup); GeometryCollectionAlgo::ParentTransform(Collection, RootIndex, BoneIndex); Transform[BoneIndex] = <some transform within local space of the RootIndex> Default collections have all geometry not parented. The function EnsureSingleRoot was added to guarantee that the collection has at least one parent node. FGeometryCollectionCommands::EnsureSinglRoot(UGeometryCollection* RestCollection) Then matrices relative to the collections root are calculated using: GlobalMatrices(UGeometryCollection* GeometryCollection, TArray<FTransform> & Transforms); Added Damage Threshold to GeometryCollectionActor ------ Change 4208039 by Brice.Criswell GeometryCollection Fix for static include failure. --- Change 4208170 by Brice.Criswell GeometryCache SplitAlongYZ to support multiple levels and orientations. --- Change 4208174 by Michael.Lentine Avoid shadow warnings and switch logs to verbose instead of warnings. #robomerge destruction Change 4210255 by Benn.Gallagher Static analysis fixes Change 4210394 by Michael.Lentine Use correct particle type for updateconstraints. Change 4211153 by Brice.Criswell Apeiron Exposing friction and coefficient of restitution to the actor. ----- Change 4213034 by michael.lentine Rename bounding volume Change 4216783 by Michael.Lentine Committing cooking fix to Dev-Physics in order to get smoke tests running. Change 4218078 by Benn.Gallagher Fixed memory and TLS slot leak caused by previous change to physics scene cleanup while cooking #jira UE-61633 Change 4219206 by Michael.Lentine Use the adaptor to get the rotation. #jira ue-61748 Change 4220469 by Benn.Gallagher Fixed overlaps re-triggering on movement due to bad transform chaining from component to phys actor to shape #jira UE-61703 Change 4220538 by Benn.Gallagher Fixed PhysX errors when setting global transforms of kinematic and static objects. #jira none Change 4222138 by Michael.Lentine Update use of Vulkan on android. Change 4222139 by Michael.Lentine Update OculusHMD plugin to use correct vulkan search path. Change 4225740 by Michael.Lentine Integrate changes to update rotation and mass. Change 4225928 by michael.lentine Use more accurate collision point. Change 4226560 by michael.lentine Enable contact graph Change 4227397 by Michael.Lentine If we don't have a global scene we need to not detect collisions. #robomerge destruction Change 4227410 by Michael.Lentine Missing include #robomerge destruction Change 4228107 by Michael.Lentine Integrate static contact changes. Change 4228612 by michael.lentine Use more correct thresholding. Change 4228734 by Benn.Gallagher Getting LLImmediate high level stood up and simulating Implementation is incomplete, only what is required to get simple scenes simulating under immediate mode Change 4228748 by Benn.Gallagher Missed file from checkin Change 4228885 by Ori.Cohen Added base physics interface class to help provide default behavior and easily chain functionality together Change 4228992 by Ori.Cohen Fix cis Change 4229921 by Benn.Gallagher Fixed contact pre-filter performance regression Change 4230825 by Benn.Gallagher Moved WIP physics interfaces to Experimental/ folders Change 4230853 by Benn.Gallagher Fixup includes after moving WIP physics interfaces Change 4231414 by Michael.Lentine Use global namespace to avoid mac compile errors. #jira ue-62137 [CL 4242847 by Michael Lentine in Main branch]
2018-07-31 02:23:26 -04:00
void FMeshMergeHelpers::TransformPhysicsGeometry(const FTransform& InTransform, const bool bBakeConvexTransform, struct FKAggregateGeom& AggGeom)
{
FTransform NoScaleInTransform = InTransform;
NoScaleInTransform.SetScale3D(FVector(1, 1, 1));
// Pre-scale all non-convex geometry
const FVector Scale3D = InTransform.GetScale3D();
if (!Scale3D.Equals(FVector(1.f)))
{
const float MinPrimSize = KINDA_SMALL_NUMBER;
for (FKSphereElem& Elem : AggGeom.SphereElems)
{
Elem = Elem.GetFinalScaled(Scale3D, FTransform::Identity);
}
for (FKBoxElem& Elem : AggGeom.BoxElems)
{
Elem = Elem.GetFinalScaled(Scale3D, FTransform::Identity);
}
for (FKSphylElem& Elem : AggGeom.SphylElems)
{
Elem = Elem.GetFinalScaled(Scale3D, FTransform::Identity);
}
}
// Multiply out merge transform (excluding scale) with original transforms for non-convex geometry
for (FKSphereElem& Elem : AggGeom.SphereElems)
{
FTransform ElemTM = Elem.GetTransform();
Elem.SetTransform(ElemTM*NoScaleInTransform);
}
for (FKBoxElem& Elem : AggGeom.BoxElems)
{
FTransform ElemTM = Elem.GetTransform();
Elem.SetTransform(ElemTM*NoScaleInTransform);
}
for (FKSphylElem& Elem : AggGeom.SphylElems)
{
FTransform ElemTM = Elem.GetTransform();
Elem.SetTransform(ElemTM*NoScaleInTransform);
}
for (FKConvexElem& Elem : AggGeom.ConvexElems)
{
FTransform ElemTM = Elem.GetTransform();
Copying //UE4/Dev-Physics to //UE4/Dev-Main (Source: //UE4/Dev-Physics @ 4242698) #rb none #lockdown Nick.Penwarden ============================ MAJOR FEATURES & CHANGES ============================ Change 4023283 by Michael.Lentine Fix memory leak. Change 4024243 by Michael.Lentine Add debugging output code from github #4533. #jira ue-55764 Change 4026362 by Michael.Lentine Merged github #3704. #jira ue-463394 Change 4026545 by Michael.Lentine Fix ordering of collision settings changed callback #jira ue-50475 Change 4026609 by Michael.Lentine Fix crash in destruction for when world is not valid #jira ue-53989 Change 4026786 by Michael.Lentine Merging github #4632 to fix memory leak. #jira ue-57255 Change 4027293 by Michael.Lentine Integrate github #4338. #jira ue-53497 Change 4033517 by Michael.Lentine Fix collision body creation for spline merging. #jira ue-53956 Change 4039750 by Michael.Lentine Add basic error message if cooking fails. Change 4040210 by Michael.Lentine Check for nullptr Change 4098887 by Michael.Lentine Fix warnings. Change 4103511 by Michael.Lentine Prevent crash when BodyInstance is invalid. Change 4117826 by Michael.Lentine Fix check for body being fixed. Change 4122307 by Benn.Gallagher PS4/clang build fixes Change 4124479 by Benn.Gallagher Fix non-portable filename used as an include (Linux editor build CIS error) Change 4125450 by Benn.Gallagher Fixup Ocean Change 4127210 by Michael.Lentine Update the PreviousBoneTransforms array when setting transforms in DestructibleComponent #jira ue-58813 Change 4127309 by Benn.Gallagher Fix Win32 shipping builds Change 4134570 by Michael.Lentine Missed fixes for WITH_UEPHYSICS. Change 4134585 by Michael.Lentine Missed a few more files. Change 4134670 by Michael.Lentine Update formatting. Change 4134671 by Michael.Lentine More formatting. Change 4150615 by Benn.Gallagher Moved immediate mode into engine, as it is now depended on by the physics engine. Change 4150680 by Benn.Gallagher Missed file Change 4150980 by Benn.Gallagher Rename kinematic target for immediate mode to avoid ambiguous symbols in engine Change 4151400 by Brice.Criswell Apeiron Levelset initilization issue. ---- Change 4157880 by Benn.Gallagher More fixing unresolved template specialisations for FN editor. Change 4159128 by Michael.Lentine Compile fixes Change 4159786 by Brice.Criswell Apeiron Levelset curvature initialization fix, clamps out of bounds phi values to phi[i]. ------ Change 4160382 by Michael.Lentine Fix node initialization Change 4160463 by Brice.Criswell Apeiron Levelset index fix. ---- Change 4161425 by Benn.Gallagher Added package, class and struct redirects for moving immediate physics into engine. Change 4164195 by Brice.Criswell GeometryCollection : Code review updates - Removed typedef for GeometryCollection::ManagedArray<T> - Renamed Enumerations to begin with E prefix, retyped to be uint8. - Removed EArrayScoipe::FScopeNone, now defautls to FScopeShared - Formatted type modifiers to follow UE4 coding standard. - Derived the ManagedArrayBase from FNonCopyable - Disabled TManagedArrays copy constructor and assignment operator. - Converted most accessors on GeometryCollection to TSharedRef. - Added .inl style definitions to simplify the management of the ManagedArrayTypes ----- Change 4164235 by Brice.Criswell GeometryCollection : Added New Files - Added the ManagedArrayTypes files. ---- Change 4164309 by Brice.Criswell GeometryCollection : Moved the initialization of the RigidBodyIdArray and CenterOfMassArray into the WITH_APEIRON definition. ----- Change 4166133 by Brice.Criswell GeometryCollection Added GeometryCollectionEdit class to protect access to the rest and dynamic collections. ----- Change 4171540 by Michael.Lentine Fix reset #robomerge destruction Change 4171912 by Michael.Lentine Rename BVHParticles #robomerge destruction Change 4172445 by Brice.Criswell Copying //UE4/Dev-Destruction to Dev-Physics (//UE4/Dev-Physics) ---- Change 4172623 by Brice.Criswell GeometryCollection Debugging ToString to inspect the GeometryCollection ---- Change 4172711 by Michael.Lentine Add Immediate Path to Geometry Collection Change 4172778 by Michael.Lentine Update LL Interface to use Simulation type. #robomerge destruction Change 4172780 by Michael.Lentine Missed files #robomerge destruction Change 4173238 by Benn.Gallagher Missed file from last checkin Change 4173554 by Benn.Gallagher Few extra changes for const correctness and actor counts Change 4174153 by Benn.Gallagher Fixed non-unity build issue from Geom Collection. Change 4175355 by Brice.Criswell GeometryCollection Separated the GeometryCollection from USE_APEIRON flag. ----- Change 4175533 by Brice.Criswell GeometryCollection Defaulting Aperion to off. ----- Change 4175761 by Michael.Lentine Fix collisions. Change 4177105 by Benn.Gallagher Another geom collection CIS fix when running without PCHs Change 4177796 by Brice.Criswell GeometryCollection - Added parenting function to manage the BoneHierarchy Array - Split collection along yz-plane. ----- Change 4177989 by Brice.Criswell GeometryCollection - Moved Hierarchy and Transform array elements into base class TransformCollection - Renamed ParticleGroup to TransformGroup. ----- Change 4178826 by Brice.Criswell Copying //UE4/Dev-Destruction to Dev-Physics (//UE4/Dev-Physics) ---- Change 4178840 by Brice.Criswell Geometry Collection Removed FORCEINLINE from GeometryCollectionEdit.GetRestCollection ---- Change 4179493 by Brice.Criswell GeometryCollection New icons. ----- Change 4182428 by Brice.Criswell Build Configuration Apeiron configuration. - Modified bCompileApeiron to enable the compilation of the Apeiron plugin. - Added bUseApeiron to enable Apeiron in the physics interfaces. Changed PhysScene_Apeiron to enable when bCompileApeiron is enabled. Disabled the GeometryCollection* Plugins in the build. ------- Change 4185886 by Brice.Criswell GeometryCollection Renaming TransformGroup. --- Change 4186389 by michael.lentine Don't create in parallel for immediate mode. Change 4186457 by michael.lentine Hack to prevent crashing when Visible is nullptr. Change 4198872 by Brice.Criswell Apeiron Clustering changes - Clustering based on hierarchy's defined within the Geometry Collection ----- Change 4199861 by Brice.Criswell GeometryCollection Disable Apeiron in the Collection. ------ Change 4200089 by Brice.Criswell GeometryCollection Updated to enable Apeiron in the GeometryCollection when the bCompileAperion flag is enabled in the UnrealBuildTool. --- Change 4200333 by Brice.Criswell Copying //UE4/Dev-Destruction to Dev-Physics (//UE4/Dev-Physics) ----- Change 4202231 by Michael.Lentine Disable collisions between adjacent bodies connected by a joint. This typically would be specified by an artist but classic PhysX always does this uncondintionally so our clients are used to this. Change 4202748 by Michael.Lentine Fix 2015 compile. Change 4204528 by Michael.Lentine Disable Apeiron. Change 4206396 by Michael.Lentine Fix 2015 build. Static cast apparently is not an accetible conversion from uint32 to bool. #robomerge destruction Change 4206604 by Michael.Lentine Fix for using ccd and kinematic. #jira UE-61694 #robomerge destruction Change 4206711 by mason.seay Refreshed Set Angular Drive nodes to clear out orphan pins Change 4207286 by Brice.Criswell GeometryCollection Transform hierarchy evaluation within BoneHierarchy of the Collection. Parenting operations are implemented on an updated morphology using : ParentTransforms(UGeometryCollection* GeometryCollection, const int32 InsertAtIndex, const TArray<int32>& SelectedBones); To parent a new transform: int32 RootIndex << within len( TransformGroup ) or -1 for a non-parented node. int32 BoneIndex = Collection->AddElements(1, UGeometryCollection::TransformGroup); GeometryCollectionAlgo::ParentTransform(Collection, RootIndex, BoneIndex); Transform[BoneIndex] = <some transform within local space of the RootIndex> Default collections have all geometry not parented. The function EnsureSingleRoot was added to guarantee that the collection has at least one parent node. FGeometryCollectionCommands::EnsureSinglRoot(UGeometryCollection* RestCollection) Then matrices relative to the collections root are calculated using: GlobalMatrices(UGeometryCollection* GeometryCollection, TArray<FTransform> & Transforms); Added Damage Threshold to GeometryCollectionActor ------ Change 4208039 by Brice.Criswell GeometryCollection Fix for static include failure. --- Change 4208170 by Brice.Criswell GeometryCache SplitAlongYZ to support multiple levels and orientations. --- Change 4208174 by Michael.Lentine Avoid shadow warnings and switch logs to verbose instead of warnings. #robomerge destruction Change 4210255 by Benn.Gallagher Static analysis fixes Change 4210394 by Michael.Lentine Use correct particle type for updateconstraints. Change 4211153 by Brice.Criswell Apeiron Exposing friction and coefficient of restitution to the actor. ----- Change 4213034 by michael.lentine Rename bounding volume Change 4216783 by Michael.Lentine Committing cooking fix to Dev-Physics in order to get smoke tests running. Change 4218078 by Benn.Gallagher Fixed memory and TLS slot leak caused by previous change to physics scene cleanup while cooking #jira UE-61633 Change 4219206 by Michael.Lentine Use the adaptor to get the rotation. #jira ue-61748 Change 4220469 by Benn.Gallagher Fixed overlaps re-triggering on movement due to bad transform chaining from component to phys actor to shape #jira UE-61703 Change 4220538 by Benn.Gallagher Fixed PhysX errors when setting global transforms of kinematic and static objects. #jira none Change 4222138 by Michael.Lentine Update use of Vulkan on android. Change 4222139 by Michael.Lentine Update OculusHMD plugin to use correct vulkan search path. Change 4225740 by Michael.Lentine Integrate changes to update rotation and mass. Change 4225928 by michael.lentine Use more accurate collision point. Change 4226560 by michael.lentine Enable contact graph Change 4227397 by Michael.Lentine If we don't have a global scene we need to not detect collisions. #robomerge destruction Change 4227410 by Michael.Lentine Missing include #robomerge destruction Change 4228107 by Michael.Lentine Integrate static contact changes. Change 4228612 by michael.lentine Use more correct thresholding. Change 4228734 by Benn.Gallagher Getting LLImmediate high level stood up and simulating Implementation is incomplete, only what is required to get simple scenes simulating under immediate mode Change 4228748 by Benn.Gallagher Missed file from checkin Change 4228885 by Ori.Cohen Added base physics interface class to help provide default behavior and easily chain functionality together Change 4228992 by Ori.Cohen Fix cis Change 4229921 by Benn.Gallagher Fixed contact pre-filter performance regression Change 4230825 by Benn.Gallagher Moved WIP physics interfaces to Experimental/ folders Change 4230853 by Benn.Gallagher Fixup includes after moving WIP physics interfaces Change 4231414 by Michael.Lentine Use global namespace to avoid mac compile errors. #jira ue-62137 [CL 4242847 by Michael Lentine in Main branch]
2018-07-31 02:23:26 -04:00
if (bBakeConvexTransform)
{
for (FVector& Position : Elem.VertexData)
{
Position = ElemTM.TransformPosition(Position);
}
Elem.SetTransform(InTransform);
}
else
{
Elem.SetTransform(ElemTM*InTransform);
}
}
}
Copying //UE4/Dev-Physics to //UE4/Dev-Main (Source: //UE4/Dev-Physics @ 4242698) #rb none #lockdown Nick.Penwarden ============================ MAJOR FEATURES & CHANGES ============================ Change 4023283 by Michael.Lentine Fix memory leak. Change 4024243 by Michael.Lentine Add debugging output code from github #4533. #jira ue-55764 Change 4026362 by Michael.Lentine Merged github #3704. #jira ue-463394 Change 4026545 by Michael.Lentine Fix ordering of collision settings changed callback #jira ue-50475 Change 4026609 by Michael.Lentine Fix crash in destruction for when world is not valid #jira ue-53989 Change 4026786 by Michael.Lentine Merging github #4632 to fix memory leak. #jira ue-57255 Change 4027293 by Michael.Lentine Integrate github #4338. #jira ue-53497 Change 4033517 by Michael.Lentine Fix collision body creation for spline merging. #jira ue-53956 Change 4039750 by Michael.Lentine Add basic error message if cooking fails. Change 4040210 by Michael.Lentine Check for nullptr Change 4098887 by Michael.Lentine Fix warnings. Change 4103511 by Michael.Lentine Prevent crash when BodyInstance is invalid. Change 4117826 by Michael.Lentine Fix check for body being fixed. Change 4122307 by Benn.Gallagher PS4/clang build fixes Change 4124479 by Benn.Gallagher Fix non-portable filename used as an include (Linux editor build CIS error) Change 4125450 by Benn.Gallagher Fixup Ocean Change 4127210 by Michael.Lentine Update the PreviousBoneTransforms array when setting transforms in DestructibleComponent #jira ue-58813 Change 4127309 by Benn.Gallagher Fix Win32 shipping builds Change 4134570 by Michael.Lentine Missed fixes for WITH_UEPHYSICS. Change 4134585 by Michael.Lentine Missed a few more files. Change 4134670 by Michael.Lentine Update formatting. Change 4134671 by Michael.Lentine More formatting. Change 4150615 by Benn.Gallagher Moved immediate mode into engine, as it is now depended on by the physics engine. Change 4150680 by Benn.Gallagher Missed file Change 4150980 by Benn.Gallagher Rename kinematic target for immediate mode to avoid ambiguous symbols in engine Change 4151400 by Brice.Criswell Apeiron Levelset initilization issue. ---- Change 4157880 by Benn.Gallagher More fixing unresolved template specialisations for FN editor. Change 4159128 by Michael.Lentine Compile fixes Change 4159786 by Brice.Criswell Apeiron Levelset curvature initialization fix, clamps out of bounds phi values to phi[i]. ------ Change 4160382 by Michael.Lentine Fix node initialization Change 4160463 by Brice.Criswell Apeiron Levelset index fix. ---- Change 4161425 by Benn.Gallagher Added package, class and struct redirects for moving immediate physics into engine. Change 4164195 by Brice.Criswell GeometryCollection : Code review updates - Removed typedef for GeometryCollection::ManagedArray<T> - Renamed Enumerations to begin with E prefix, retyped to be uint8. - Removed EArrayScoipe::FScopeNone, now defautls to FScopeShared - Formatted type modifiers to follow UE4 coding standard. - Derived the ManagedArrayBase from FNonCopyable - Disabled TManagedArrays copy constructor and assignment operator. - Converted most accessors on GeometryCollection to TSharedRef. - Added .inl style definitions to simplify the management of the ManagedArrayTypes ----- Change 4164235 by Brice.Criswell GeometryCollection : Added New Files - Added the ManagedArrayTypes files. ---- Change 4164309 by Brice.Criswell GeometryCollection : Moved the initialization of the RigidBodyIdArray and CenterOfMassArray into the WITH_APEIRON definition. ----- Change 4166133 by Brice.Criswell GeometryCollection Added GeometryCollectionEdit class to protect access to the rest and dynamic collections. ----- Change 4171540 by Michael.Lentine Fix reset #robomerge destruction Change 4171912 by Michael.Lentine Rename BVHParticles #robomerge destruction Change 4172445 by Brice.Criswell Copying //UE4/Dev-Destruction to Dev-Physics (//UE4/Dev-Physics) ---- Change 4172623 by Brice.Criswell GeometryCollection Debugging ToString to inspect the GeometryCollection ---- Change 4172711 by Michael.Lentine Add Immediate Path to Geometry Collection Change 4172778 by Michael.Lentine Update LL Interface to use Simulation type. #robomerge destruction Change 4172780 by Michael.Lentine Missed files #robomerge destruction Change 4173238 by Benn.Gallagher Missed file from last checkin Change 4173554 by Benn.Gallagher Few extra changes for const correctness and actor counts Change 4174153 by Benn.Gallagher Fixed non-unity build issue from Geom Collection. Change 4175355 by Brice.Criswell GeometryCollection Separated the GeometryCollection from USE_APEIRON flag. ----- Change 4175533 by Brice.Criswell GeometryCollection Defaulting Aperion to off. ----- Change 4175761 by Michael.Lentine Fix collisions. Change 4177105 by Benn.Gallagher Another geom collection CIS fix when running without PCHs Change 4177796 by Brice.Criswell GeometryCollection - Added parenting function to manage the BoneHierarchy Array - Split collection along yz-plane. ----- Change 4177989 by Brice.Criswell GeometryCollection - Moved Hierarchy and Transform array elements into base class TransformCollection - Renamed ParticleGroup to TransformGroup. ----- Change 4178826 by Brice.Criswell Copying //UE4/Dev-Destruction to Dev-Physics (//UE4/Dev-Physics) ---- Change 4178840 by Brice.Criswell Geometry Collection Removed FORCEINLINE from GeometryCollectionEdit.GetRestCollection ---- Change 4179493 by Brice.Criswell GeometryCollection New icons. ----- Change 4182428 by Brice.Criswell Build Configuration Apeiron configuration. - Modified bCompileApeiron to enable the compilation of the Apeiron plugin. - Added bUseApeiron to enable Apeiron in the physics interfaces. Changed PhysScene_Apeiron to enable when bCompileApeiron is enabled. Disabled the GeometryCollection* Plugins in the build. ------- Change 4185886 by Brice.Criswell GeometryCollection Renaming TransformGroup. --- Change 4186389 by michael.lentine Don't create in parallel for immediate mode. Change 4186457 by michael.lentine Hack to prevent crashing when Visible is nullptr. Change 4198872 by Brice.Criswell Apeiron Clustering changes - Clustering based on hierarchy's defined within the Geometry Collection ----- Change 4199861 by Brice.Criswell GeometryCollection Disable Apeiron in the Collection. ------ Change 4200089 by Brice.Criswell GeometryCollection Updated to enable Apeiron in the GeometryCollection when the bCompileAperion flag is enabled in the UnrealBuildTool. --- Change 4200333 by Brice.Criswell Copying //UE4/Dev-Destruction to Dev-Physics (//UE4/Dev-Physics) ----- Change 4202231 by Michael.Lentine Disable collisions between adjacent bodies connected by a joint. This typically would be specified by an artist but classic PhysX always does this uncondintionally so our clients are used to this. Change 4202748 by Michael.Lentine Fix 2015 compile. Change 4204528 by Michael.Lentine Disable Apeiron. Change 4206396 by Michael.Lentine Fix 2015 build. Static cast apparently is not an accetible conversion from uint32 to bool. #robomerge destruction Change 4206604 by Michael.Lentine Fix for using ccd and kinematic. #jira UE-61694 #robomerge destruction Change 4206711 by mason.seay Refreshed Set Angular Drive nodes to clear out orphan pins Change 4207286 by Brice.Criswell GeometryCollection Transform hierarchy evaluation within BoneHierarchy of the Collection. Parenting operations are implemented on an updated morphology using : ParentTransforms(UGeometryCollection* GeometryCollection, const int32 InsertAtIndex, const TArray<int32>& SelectedBones); To parent a new transform: int32 RootIndex << within len( TransformGroup ) or -1 for a non-parented node. int32 BoneIndex = Collection->AddElements(1, UGeometryCollection::TransformGroup); GeometryCollectionAlgo::ParentTransform(Collection, RootIndex, BoneIndex); Transform[BoneIndex] = <some transform within local space of the RootIndex> Default collections have all geometry not parented. The function EnsureSingleRoot was added to guarantee that the collection has at least one parent node. FGeometryCollectionCommands::EnsureSinglRoot(UGeometryCollection* RestCollection) Then matrices relative to the collections root are calculated using: GlobalMatrices(UGeometryCollection* GeometryCollection, TArray<FTransform> & Transforms); Added Damage Threshold to GeometryCollectionActor ------ Change 4208039 by Brice.Criswell GeometryCollection Fix for static include failure. --- Change 4208170 by Brice.Criswell GeometryCache SplitAlongYZ to support multiple levels and orientations. --- Change 4208174 by Michael.Lentine Avoid shadow warnings and switch logs to verbose instead of warnings. #robomerge destruction Change 4210255 by Benn.Gallagher Static analysis fixes Change 4210394 by Michael.Lentine Use correct particle type for updateconstraints. Change 4211153 by Brice.Criswell Apeiron Exposing friction and coefficient of restitution to the actor. ----- Change 4213034 by michael.lentine Rename bounding volume Change 4216783 by Michael.Lentine Committing cooking fix to Dev-Physics in order to get smoke tests running. Change 4218078 by Benn.Gallagher Fixed memory and TLS slot leak caused by previous change to physics scene cleanup while cooking #jira UE-61633 Change 4219206 by Michael.Lentine Use the adaptor to get the rotation. #jira ue-61748 Change 4220469 by Benn.Gallagher Fixed overlaps re-triggering on movement due to bad transform chaining from component to phys actor to shape #jira UE-61703 Change 4220538 by Benn.Gallagher Fixed PhysX errors when setting global transforms of kinematic and static objects. #jira none Change 4222138 by Michael.Lentine Update use of Vulkan on android. Change 4222139 by Michael.Lentine Update OculusHMD plugin to use correct vulkan search path. Change 4225740 by Michael.Lentine Integrate changes to update rotation and mass. Change 4225928 by michael.lentine Use more accurate collision point. Change 4226560 by michael.lentine Enable contact graph Change 4227397 by Michael.Lentine If we don't have a global scene we need to not detect collisions. #robomerge destruction Change 4227410 by Michael.Lentine Missing include #robomerge destruction Change 4228107 by Michael.Lentine Integrate static contact changes. Change 4228612 by michael.lentine Use more correct thresholding. Change 4228734 by Benn.Gallagher Getting LLImmediate high level stood up and simulating Implementation is incomplete, only what is required to get simple scenes simulating under immediate mode Change 4228748 by Benn.Gallagher Missed file from checkin Change 4228885 by Ori.Cohen Added base physics interface class to help provide default behavior and easily chain functionality together Change 4228992 by Ori.Cohen Fix cis Change 4229921 by Benn.Gallagher Fixed contact pre-filter performance regression Change 4230825 by Benn.Gallagher Moved WIP physics interfaces to Experimental/ folders Change 4230853 by Benn.Gallagher Fixup includes after moving WIP physics interfaces Change 4231414 by Michael.Lentine Use global namespace to avoid mac compile errors. #jira ue-62137 [CL 4242847 by Michael Lentine in Main branch]
2018-07-31 02:23:26 -04:00
void FMeshMergeHelpers::ExtractPhysicsGeometry(UBodySetup* InBodySetup, const FTransform& ComponentToWorld, const bool bBakeConvexTransform, struct FKAggregateGeom& OutAggGeom)
{
if (InBodySetup == nullptr)
{
return;
}
OutAggGeom = InBodySetup->AggGeom;
// Convert boxes to convex, so they can be sheared
for (int32 BoxIdx = 0; BoxIdx < OutAggGeom.BoxElems.Num(); BoxIdx++)
{
FKConvexElem* NewConvexColl = new(OutAggGeom.ConvexElems) FKConvexElem();
NewConvexColl->ConvexFromBoxElem(OutAggGeom.BoxElems[BoxIdx]);
}
OutAggGeom.BoxElems.Empty();
// we are not owner of this stuff
OutAggGeom.RenderInfo = nullptr;
for (FKConvexElem& Elem : OutAggGeom.ConvexElems)
{
#if PHYSICS_INTERFACE_PHYSX
Elem.SetConvexMesh(nullptr);
Elem.SetMirroredConvexMesh(nullptr);
#elif WITH_CHAOS
Elem.ResetChaosConvexMesh();
#endif
}
// Transform geometry to world space
Copying //UE4/Dev-Physics to //UE4/Dev-Main (Source: //UE4/Dev-Physics @ 4242698) #rb none #lockdown Nick.Penwarden ============================ MAJOR FEATURES & CHANGES ============================ Change 4023283 by Michael.Lentine Fix memory leak. Change 4024243 by Michael.Lentine Add debugging output code from github #4533. #jira ue-55764 Change 4026362 by Michael.Lentine Merged github #3704. #jira ue-463394 Change 4026545 by Michael.Lentine Fix ordering of collision settings changed callback #jira ue-50475 Change 4026609 by Michael.Lentine Fix crash in destruction for when world is not valid #jira ue-53989 Change 4026786 by Michael.Lentine Merging github #4632 to fix memory leak. #jira ue-57255 Change 4027293 by Michael.Lentine Integrate github #4338. #jira ue-53497 Change 4033517 by Michael.Lentine Fix collision body creation for spline merging. #jira ue-53956 Change 4039750 by Michael.Lentine Add basic error message if cooking fails. Change 4040210 by Michael.Lentine Check for nullptr Change 4098887 by Michael.Lentine Fix warnings. Change 4103511 by Michael.Lentine Prevent crash when BodyInstance is invalid. Change 4117826 by Michael.Lentine Fix check for body being fixed. Change 4122307 by Benn.Gallagher PS4/clang build fixes Change 4124479 by Benn.Gallagher Fix non-portable filename used as an include (Linux editor build CIS error) Change 4125450 by Benn.Gallagher Fixup Ocean Change 4127210 by Michael.Lentine Update the PreviousBoneTransforms array when setting transforms in DestructibleComponent #jira ue-58813 Change 4127309 by Benn.Gallagher Fix Win32 shipping builds Change 4134570 by Michael.Lentine Missed fixes for WITH_UEPHYSICS. Change 4134585 by Michael.Lentine Missed a few more files. Change 4134670 by Michael.Lentine Update formatting. Change 4134671 by Michael.Lentine More formatting. Change 4150615 by Benn.Gallagher Moved immediate mode into engine, as it is now depended on by the physics engine. Change 4150680 by Benn.Gallagher Missed file Change 4150980 by Benn.Gallagher Rename kinematic target for immediate mode to avoid ambiguous symbols in engine Change 4151400 by Brice.Criswell Apeiron Levelset initilization issue. ---- Change 4157880 by Benn.Gallagher More fixing unresolved template specialisations for FN editor. Change 4159128 by Michael.Lentine Compile fixes Change 4159786 by Brice.Criswell Apeiron Levelset curvature initialization fix, clamps out of bounds phi values to phi[i]. ------ Change 4160382 by Michael.Lentine Fix node initialization Change 4160463 by Brice.Criswell Apeiron Levelset index fix. ---- Change 4161425 by Benn.Gallagher Added package, class and struct redirects for moving immediate physics into engine. Change 4164195 by Brice.Criswell GeometryCollection : Code review updates - Removed typedef for GeometryCollection::ManagedArray<T> - Renamed Enumerations to begin with E prefix, retyped to be uint8. - Removed EArrayScoipe::FScopeNone, now defautls to FScopeShared - Formatted type modifiers to follow UE4 coding standard. - Derived the ManagedArrayBase from FNonCopyable - Disabled TManagedArrays copy constructor and assignment operator. - Converted most accessors on GeometryCollection to TSharedRef. - Added .inl style definitions to simplify the management of the ManagedArrayTypes ----- Change 4164235 by Brice.Criswell GeometryCollection : Added New Files - Added the ManagedArrayTypes files. ---- Change 4164309 by Brice.Criswell GeometryCollection : Moved the initialization of the RigidBodyIdArray and CenterOfMassArray into the WITH_APEIRON definition. ----- Change 4166133 by Brice.Criswell GeometryCollection Added GeometryCollectionEdit class to protect access to the rest and dynamic collections. ----- Change 4171540 by Michael.Lentine Fix reset #robomerge destruction Change 4171912 by Michael.Lentine Rename BVHParticles #robomerge destruction Change 4172445 by Brice.Criswell Copying //UE4/Dev-Destruction to Dev-Physics (//UE4/Dev-Physics) ---- Change 4172623 by Brice.Criswell GeometryCollection Debugging ToString to inspect the GeometryCollection ---- Change 4172711 by Michael.Lentine Add Immediate Path to Geometry Collection Change 4172778 by Michael.Lentine Update LL Interface to use Simulation type. #robomerge destruction Change 4172780 by Michael.Lentine Missed files #robomerge destruction Change 4173238 by Benn.Gallagher Missed file from last checkin Change 4173554 by Benn.Gallagher Few extra changes for const correctness and actor counts Change 4174153 by Benn.Gallagher Fixed non-unity build issue from Geom Collection. Change 4175355 by Brice.Criswell GeometryCollection Separated the GeometryCollection from USE_APEIRON flag. ----- Change 4175533 by Brice.Criswell GeometryCollection Defaulting Aperion to off. ----- Change 4175761 by Michael.Lentine Fix collisions. Change 4177105 by Benn.Gallagher Another geom collection CIS fix when running without PCHs Change 4177796 by Brice.Criswell GeometryCollection - Added parenting function to manage the BoneHierarchy Array - Split collection along yz-plane. ----- Change 4177989 by Brice.Criswell GeometryCollection - Moved Hierarchy and Transform array elements into base class TransformCollection - Renamed ParticleGroup to TransformGroup. ----- Change 4178826 by Brice.Criswell Copying //UE4/Dev-Destruction to Dev-Physics (//UE4/Dev-Physics) ---- Change 4178840 by Brice.Criswell Geometry Collection Removed FORCEINLINE from GeometryCollectionEdit.GetRestCollection ---- Change 4179493 by Brice.Criswell GeometryCollection New icons. ----- Change 4182428 by Brice.Criswell Build Configuration Apeiron configuration. - Modified bCompileApeiron to enable the compilation of the Apeiron plugin. - Added bUseApeiron to enable Apeiron in the physics interfaces. Changed PhysScene_Apeiron to enable when bCompileApeiron is enabled. Disabled the GeometryCollection* Plugins in the build. ------- Change 4185886 by Brice.Criswell GeometryCollection Renaming TransformGroup. --- Change 4186389 by michael.lentine Don't create in parallel for immediate mode. Change 4186457 by michael.lentine Hack to prevent crashing when Visible is nullptr. Change 4198872 by Brice.Criswell Apeiron Clustering changes - Clustering based on hierarchy's defined within the Geometry Collection ----- Change 4199861 by Brice.Criswell GeometryCollection Disable Apeiron in the Collection. ------ Change 4200089 by Brice.Criswell GeometryCollection Updated to enable Apeiron in the GeometryCollection when the bCompileAperion flag is enabled in the UnrealBuildTool. --- Change 4200333 by Brice.Criswell Copying //UE4/Dev-Destruction to Dev-Physics (//UE4/Dev-Physics) ----- Change 4202231 by Michael.Lentine Disable collisions between adjacent bodies connected by a joint. This typically would be specified by an artist but classic PhysX always does this uncondintionally so our clients are used to this. Change 4202748 by Michael.Lentine Fix 2015 compile. Change 4204528 by Michael.Lentine Disable Apeiron. Change 4206396 by Michael.Lentine Fix 2015 build. Static cast apparently is not an accetible conversion from uint32 to bool. #robomerge destruction Change 4206604 by Michael.Lentine Fix for using ccd and kinematic. #jira UE-61694 #robomerge destruction Change 4206711 by mason.seay Refreshed Set Angular Drive nodes to clear out orphan pins Change 4207286 by Brice.Criswell GeometryCollection Transform hierarchy evaluation within BoneHierarchy of the Collection. Parenting operations are implemented on an updated morphology using : ParentTransforms(UGeometryCollection* GeometryCollection, const int32 InsertAtIndex, const TArray<int32>& SelectedBones); To parent a new transform: int32 RootIndex << within len( TransformGroup ) or -1 for a non-parented node. int32 BoneIndex = Collection->AddElements(1, UGeometryCollection::TransformGroup); GeometryCollectionAlgo::ParentTransform(Collection, RootIndex, BoneIndex); Transform[BoneIndex] = <some transform within local space of the RootIndex> Default collections have all geometry not parented. The function EnsureSingleRoot was added to guarantee that the collection has at least one parent node. FGeometryCollectionCommands::EnsureSinglRoot(UGeometryCollection* RestCollection) Then matrices relative to the collections root are calculated using: GlobalMatrices(UGeometryCollection* GeometryCollection, TArray<FTransform> & Transforms); Added Damage Threshold to GeometryCollectionActor ------ Change 4208039 by Brice.Criswell GeometryCollection Fix for static include failure. --- Change 4208170 by Brice.Criswell GeometryCache SplitAlongYZ to support multiple levels and orientations. --- Change 4208174 by Michael.Lentine Avoid shadow warnings and switch logs to verbose instead of warnings. #robomerge destruction Change 4210255 by Benn.Gallagher Static analysis fixes Change 4210394 by Michael.Lentine Use correct particle type for updateconstraints. Change 4211153 by Brice.Criswell Apeiron Exposing friction and coefficient of restitution to the actor. ----- Change 4213034 by michael.lentine Rename bounding volume Change 4216783 by Michael.Lentine Committing cooking fix to Dev-Physics in order to get smoke tests running. Change 4218078 by Benn.Gallagher Fixed memory and TLS slot leak caused by previous change to physics scene cleanup while cooking #jira UE-61633 Change 4219206 by Michael.Lentine Use the adaptor to get the rotation. #jira ue-61748 Change 4220469 by Benn.Gallagher Fixed overlaps re-triggering on movement due to bad transform chaining from component to phys actor to shape #jira UE-61703 Change 4220538 by Benn.Gallagher Fixed PhysX errors when setting global transforms of kinematic and static objects. #jira none Change 4222138 by Michael.Lentine Update use of Vulkan on android. Change 4222139 by Michael.Lentine Update OculusHMD plugin to use correct vulkan search path. Change 4225740 by Michael.Lentine Integrate changes to update rotation and mass. Change 4225928 by michael.lentine Use more accurate collision point. Change 4226560 by michael.lentine Enable contact graph Change 4227397 by Michael.Lentine If we don't have a global scene we need to not detect collisions. #robomerge destruction Change 4227410 by Michael.Lentine Missing include #robomerge destruction Change 4228107 by Michael.Lentine Integrate static contact changes. Change 4228612 by michael.lentine Use more correct thresholding. Change 4228734 by Benn.Gallagher Getting LLImmediate high level stood up and simulating Implementation is incomplete, only what is required to get simple scenes simulating under immediate mode Change 4228748 by Benn.Gallagher Missed file from checkin Change 4228885 by Ori.Cohen Added base physics interface class to help provide default behavior and easily chain functionality together Change 4228992 by Ori.Cohen Fix cis Change 4229921 by Benn.Gallagher Fixed contact pre-filter performance regression Change 4230825 by Benn.Gallagher Moved WIP physics interfaces to Experimental/ folders Change 4230853 by Benn.Gallagher Fixup includes after moving WIP physics interfaces Change 4231414 by Michael.Lentine Use global namespace to avoid mac compile errors. #jira ue-62137 [CL 4242847 by Michael Lentine in Main branch]
2018-07-31 02:23:26 -04:00
TransformPhysicsGeometry(ComponentToWorld, bBakeConvexTransform, OutAggGeom);
}
FVector2D FMeshMergeHelpers::GetValidUV(const FVector2D& UV)
{
FVector2D NewUV = UV;
// first make sure they're positive
if (UV.X < 0.0f)
{
NewUV.X = UV.X + FMath::CeilToInt(FMath::Abs(UV.X));
}
if (UV.Y < 0.0f)
{
NewUV.Y = UV.Y + FMath::CeilToInt(FMath::Abs(UV.Y));
}
// now make sure they're within [0, 1]
if (UV.X > 1.0f)
{
NewUV.X = FMath::Fmod(NewUV.X, 1.0f);
}
if (UV.Y > 1.0f)
{
NewUV.Y = FMath::Fmod(NewUV.Y, 1.0f);
}
return NewUV;
}
void FMeshMergeHelpers::CalculateTextureCoordinateBoundsForMesh(const FMeshDescription& InMeshDescription, TArray<FBox2D>& OutBounds)
{
TVertexInstanceAttributesConstRef<FVector2f> VertexInstanceUVs = FStaticMeshConstAttributes(InMeshDescription).GetVertexInstanceUVs();
OutBounds.Empty();
for (const FTriangleID TriangleID : InMeshDescription.Polygons().GetElementIDs())
{
int32 MaterialIndex = InMeshDescription.GetTrianglePolygonGroup(TriangleID).GetValue();
if (OutBounds.Num() <= MaterialIndex)
OutBounds.SetNumZeroed(MaterialIndex + 1);
{
TArrayView<const FVertexInstanceID> TriangleVertexInstances = InMeshDescription.GetTriangleVertexInstances(TriangleID);
First pass of MeshDescription API and format refactor. - Removed hardcoded element type arrays (Vertices, Edges, Triangles etc.). Mesh element types can now be arbitrarily added, with any number of channels. - Mesh element containers have a much leaner format; instead of sparse arrays, they are now represented by a simple bitarray, determining whether an index is used or not. Consequently, mesh topology is now entirely described with the attribute system, e.g. edge start and end vertices, triangle vertices, etc. - Support added for attributes of arbitrary dimensions, e.g. float[4] or int[2]. - Support added for attributes which index into another mesh element container. - Added FMeshElementIndexer: this is an efficient container for maintaining backward references from one element type to another; for example, edges have an attribute specifying which vertices are at each end (an attribute of type FVertexID[2]). With an indexer, it is possible to look up which edges contain a given vertex, even though this is not explicitly stored. Indexers are designed to do minimal allocations and update lazily and in batch when necessary. - Added support for preserving UV topology in static meshes. UVs are now a first-class element type which may be indexed directly from triangles. - Added the facility to access the underlying array in an attribute array directly. - Triangles now directly reference their vertex, edge and UV IDs. Vertex instances are to be deprecated. - Changed various systems to be triangle-centric rather than polygon-centric, as this is faster. Triangles are presumed to be the elementary face type in a MeshDescription, even if polygons are still supported. The concept of polygons will be somewhat shifted to mean a group of triangles which should be treated collectively for editing purposes. - Optimised normal/tangent generation and FBX import. - Deprecated EditableMesh, MeshEditor and StaticMeshEditorExtension plugins - these are to be removed, but they still have certain hooks in place which need removing. #rb [CL 13568702 by Richard TalbotWatkin in ue5-main branch]
2020-05-28 10:56:57 -04:00
for (const FVertexInstanceID VertexInstanceID : TriangleVertexInstances)
{
First pass of MeshDescription API and format refactor. - Removed hardcoded element type arrays (Vertices, Edges, Triangles etc.). Mesh element types can now be arbitrarily added, with any number of channels. - Mesh element containers have a much leaner format; instead of sparse arrays, they are now represented by a simple bitarray, determining whether an index is used or not. Consequently, mesh topology is now entirely described with the attribute system, e.g. edge start and end vertices, triangle vertices, etc. - Support added for attributes of arbitrary dimensions, e.g. float[4] or int[2]. - Support added for attributes which index into another mesh element container. - Added FMeshElementIndexer: this is an efficient container for maintaining backward references from one element type to another; for example, edges have an attribute specifying which vertices are at each end (an attribute of type FVertexID[2]). With an indexer, it is possible to look up which edges contain a given vertex, even though this is not explicitly stored. Indexers are designed to do minimal allocations and update lazily and in batch when necessary. - Added support for preserving UV topology in static meshes. UVs are now a first-class element type which may be indexed directly from triangles. - Added the facility to access the underlying array in an attribute array directly. - Triangles now directly reference their vertex, edge and UV IDs. Vertex instances are to be deprecated. - Changed various systems to be triangle-centric rather than polygon-centric, as this is faster. Triangles are presumed to be the elementary face type in a MeshDescription, even if polygons are still supported. The concept of polygons will be somewhat shifted to mean a group of triangles which should be treated collectively for editing purposes. - Optimised normal/tangent generation and FBX import. - Deprecated EditableMesh, MeshEditor and StaticMeshEditorExtension plugins - these are to be removed, but they still have certain hooks in place which need removing. #rb [CL 13568702 by Richard TalbotWatkin in ue5-main branch]
2020-05-28 10:56:57 -04:00
for (int32 UVIndex = 0; UVIndex < VertexInstanceUVs.GetNumChannels(); ++UVIndex)
{
OutBounds[MaterialIndex] += FVector2D(VertexInstanceUVs.Get(VertexInstanceID, UVIndex));
}
}
}
}
}
bool FMeshMergeHelpers::PropagatePaintedColorsToMesh(const UStaticMeshComponent* StaticMeshComponent, int32 LODIndex, FMeshDescription& InOutMeshDescription)
{
if (StaticMeshComponent->LODData.IsValidIndex(LODIndex) &&
StaticMeshComponent->LODData[LODIndex].OverrideVertexColors != nullptr)
{
FColorVertexBuffer& ColorVertexBuffer = *StaticMeshComponent->LODData[LODIndex].OverrideVertexColors;
const UStaticMesh& StaticMesh = *StaticMeshComponent->GetStaticMesh();
if (ColorVertexBuffer.GetNumVertices() == StaticMesh.GetNumVertices(LODIndex))
{
const FStaticMeshLODResources& RenderModel = StaticMesh.GetRenderData()->LODResources[LODIndex];
const int32 NumWedges = InOutMeshDescription.VertexInstances().Num();
const int32 NumRenderWedges = RenderModel.IndexBuffer.GetNumIndices();
const bool bUseRenderWedges = NumWedges == NumRenderWedges;
TVertexInstanceAttributesRef<FVector4f> VertexInstanceColors = FStaticMeshAttributes(InOutMeshDescription).GetVertexInstanceColors();
if (bUseRenderWedges)
{
//Create a map index
TMap<int32, FVertexInstanceID> IndexToVertexInstanceID;
IndexToVertexInstanceID.Reserve(NumWedges);
int32 CurrentWedgeIndex = 0;
for (const FTriangleID TriangleID : InOutMeshDescription.Triangles().GetElementIDs())
{
for (int32 Corner = 0; Corner < 3; ++Corner, ++CurrentWedgeIndex)
{
IndexToVertexInstanceID.Add(CurrentWedgeIndex, InOutMeshDescription.GetTriangleVertexInstance(TriangleID, Corner));
}
}
const FIndexArrayView ArrayView = RenderModel.IndexBuffer.GetArrayView();
for (int32 WedgeIndex = 0; WedgeIndex < NumRenderWedges; WedgeIndex++)
{
const int32 Index = ArrayView[WedgeIndex];
FColor WedgeColor = FColor::White;
if (Index != INDEX_NONE)
{
WedgeColor = ColorVertexBuffer.VertexColor(Index);
}
VertexInstanceColors[IndexToVertexInstanceID[WedgeIndex]] = FLinearColor(WedgeColor);
}
return true;
}
// No wedge map (this can happen when we poly reduce the LOD for example)
// Use index buffer directly. Not sure this will happen with FMeshDescription
else
{
if (InOutMeshDescription.Vertices().Num() == ColorVertexBuffer.GetNumVertices())
{
//Create a map index
TMap<FVertexID, int32> VertexIDToVertexIndex;
VertexIDToVertexIndex.Reserve(InOutMeshDescription.Vertices().Num());
int32 CurrentVertexIndex = 0;
for (const FVertexID VertexID : InOutMeshDescription.Vertices().GetElementIDs())
{
VertexIDToVertexIndex.Add(VertexID, CurrentVertexIndex++);
}
for (const FVertexID VertexID : InOutMeshDescription.Vertices().GetElementIDs())
{
FColor WedgeColor = FColor::White;
uint32 VertIndex = VertexIDToVertexIndex[VertexID];
if (VertIndex < ColorVertexBuffer.GetNumVertices())
{
WedgeColor = ColorVertexBuffer.VertexColor(VertIndex);
}
TArrayView<const FVertexInstanceID> VertexInstances = InOutMeshDescription.GetVertexVertexInstanceIDs(VertexID);
for (const FVertexInstanceID& VertexInstanceID : VertexInstances)
{
VertexInstanceColors[VertexInstanceID] = FLinearColor(WedgeColor);
}
}
return true;
}
}
}
}
return false;
}
bool FMeshMergeHelpers::IsLandscapeHit(const FVector& RayOrigin, const FVector& RayEndPoint, const UWorld* World, const TArray<ALandscapeProxy*>& LandscapeProxies, FVector& OutHitLocation)
{
TArray<FHitResult> Results;
// Each landscape component has 2 collision shapes, 1 of them is specific to landscape editor
// Trace only ECC_Visibility channel, so we do hit only Editor specific shape
World->LineTraceMultiByObjectType(Results, RayOrigin, RayEndPoint, FCollisionObjectQueryParams(ECollisionChannel::ECC_WorldStatic), FCollisionQueryParams(SCENE_QUERY_STAT(LandscapeTrace), true));
bool bHitLandscape = false;
for (const FHitResult& HitResult : Results)
{
ULandscapeHeightfieldCollisionComponent* CollisionComponent = Cast<ULandscapeHeightfieldCollisionComponent>(HitResult.Component.Get());
if (CollisionComponent)
{
ALandscapeProxy* HitLandscape = CollisionComponent->GetLandscapeProxy();
if (HitLandscape && LandscapeProxies.Contains(HitLandscape))
{
// Could write a correct clipping algorithm, that clips the triangle to hit location
OutHitLocation = HitLandscape->LandscapeActorToWorld().InverseTransformPosition(HitResult.Location);
// Above landscape so visible
bHitLandscape = true;
}
}
}
return bHitLandscape;
}
void FMeshMergeHelpers::MergeImpostersToMesh(TArray<const UStaticMeshComponent*> ImposterComponents, FMeshDescription& InMeshDescription, const FVector& InPivot, int32 InBaseMaterialIndex, TArray<UMaterialInterface*>& OutImposterMaterials)
{
TMap<UMaterialInterface*, FPolygonGroupID> ImposterMaterialToPolygonGroupID;
for (const UStaticMeshComponent* Component : ImposterComponents)
{
// Retrieve imposter LOD mesh and material
const int32 LODIndex = Component->GetStaticMesh()->GetNumLODs() - 1;
// Retrieve mesh data in FMeshDescription form
FMeshDescription ImposterMesh;
FStaticMeshAttributes ImposterMeshAttributes(ImposterMesh);
ImposterMeshAttributes.Register();
FMeshMergeHelpers::RetrieveMesh(Component, LODIndex, ImposterMesh, false);
// Retrieve the sections, we're expect 1 for imposter meshes
TArray<FSectionInfo> Sections;
FMeshMergeHelpers::ExtractSections(Component, LODIndex, Sections);
TArray<int32> SectionImposterUniqueMaterialIndex;
for (FSectionInfo& Info : Sections)
{
SectionImposterUniqueMaterialIndex.Add(OutImposterMaterials.AddUnique(Info.Material));
}
if (CVarMeshMergeStoreImposterInfoInUVs.GetValueOnAnyThread())
{
// Imposter magic, we're storing the actor world position and X scale spread across two UV channels
const int32 UVOneIndex = 2;
const int32 UVTwoIndex = UVOneIndex + 1;
TVertexInstanceAttributesRef<FVector2f> VertexInstanceUVs = ImposterMeshAttributes.GetVertexInstanceUVs();
First pass of MeshDescription API and format refactor. - Removed hardcoded element type arrays (Vertices, Edges, Triangles etc.). Mesh element types can now be arbitrarily added, with any number of channels. - Mesh element containers have a much leaner format; instead of sparse arrays, they are now represented by a simple bitarray, determining whether an index is used or not. Consequently, mesh topology is now entirely described with the attribute system, e.g. edge start and end vertices, triangle vertices, etc. - Support added for attributes of arbitrary dimensions, e.g. float[4] or int[2]. - Support added for attributes which index into another mesh element container. - Added FMeshElementIndexer: this is an efficient container for maintaining backward references from one element type to another; for example, edges have an attribute specifying which vertices are at each end (an attribute of type FVertexID[2]). With an indexer, it is possible to look up which edges contain a given vertex, even though this is not explicitly stored. Indexers are designed to do minimal allocations and update lazily and in batch when necessary. - Added support for preserving UV topology in static meshes. UVs are now a first-class element type which may be indexed directly from triangles. - Added the facility to access the underlying array in an attribute array directly. - Triangles now directly reference their vertex, edge and UV IDs. Vertex instances are to be deprecated. - Changed various systems to be triangle-centric rather than polygon-centric, as this is faster. Triangles are presumed to be the elementary face type in a MeshDescription, even if polygons are still supported. The concept of polygons will be somewhat shifted to mean a group of triangles which should be treated collectively for editing purposes. - Optimised normal/tangent generation and FBX import. - Deprecated EditableMesh, MeshEditor and StaticMeshEditorExtension plugins - these are to be removed, but they still have certain hooks in place which need removing. #rb [CL 13568702 by Richard TalbotWatkin in ue5-main branch]
2020-05-28 10:56:57 -04:00
VertexInstanceUVs.SetNumChannels(UVTwoIndex + 1);
const int32 NumIndices = ImposterMesh.VertexInstances().Num();
const FTransform& ActorToWorld = Component->GetOwner()->GetActorTransform();
const FVector ActorPosition = ActorToWorld.TransformPosition(FVector::ZeroVector) - InPivot;
for (const FVertexInstanceID VertexInstanceID : ImposterMesh.VertexInstances().GetElementIDs())
{
FVector2D UVOne;
FVector2D UVTwo;
UVOne.X = ActorPosition.X;
UVOne.Y = ActorPosition.Y;
VertexInstanceUVs.Set(VertexInstanceID, UVOneIndex, FVector2f(UVOne)); // LWC_TODO: Precision loss
UVTwo.X = ActorPosition.Z;
UVTwo.Y = FMath::Abs(ActorToWorld.GetScale3D().X);
VertexInstanceUVs.Set(VertexInstanceID, UVTwoIndex, FVector2f(UVTwo)); // LWC_TODO: Precision loss
}
}
else if (!InPivot.IsZero())
{
// Apply pivot offset if non null
TVertexAttributesRef<FVector3f> ImposterMeshVertexPositions = ImposterMesh.GetVertexPositions();
for (FVertexID VertexID : ImposterMesh.Vertices().GetElementIDs())
{
ImposterMeshVertexPositions[VertexID] -= (FVector3f)InPivot;
}
}
TPolygonGroupAttributesRef<FName> SourcePolygonGroupImportedMaterialSlotNames = ImposterMeshAttributes.GetPolygonGroupMaterialSlotNames();
FStaticMeshAttributes Attributes(InMeshDescription);
TPolygonGroupAttributesRef<FName> TargetPolygonGroupImportedMaterialSlotNames = Attributes.GetPolygonGroupMaterialSlotNames();
FStaticMeshOperations::FAppendSettings AppendSettings;
//Add the missing polygon group ID to the target(InMeshDescription)
//Remap the source mesh(ImposterMesh) polygongroup to fit with the target polygon groups
AppendSettings.PolygonGroupsDelegate = FAppendPolygonGroupsDelegate::CreateLambda([&](const FMeshDescription& SourceMesh, FMeshDescription& TargetMesh, PolygonGroupMap& RemapPolygonGroups)
{
RemapPolygonGroups.Reserve(SourceMesh.PolygonGroups().Num());
int32 SectionIndex = 0;
for (const FPolygonGroupID SourcePolygonGroupID : SourceMesh.PolygonGroups().GetElementIDs())
{
UMaterialInterface* MaterialUseBySection = OutImposterMaterials[SectionImposterUniqueMaterialIndex[SectionIndex++]];
FPolygonGroupID* ExistTargetPolygonGroupID = ImposterMaterialToPolygonGroupID.Find(MaterialUseBySection);
FPolygonGroupID MatchTargetPolygonGroupID = ExistTargetPolygonGroupID == nullptr ? INDEX_NONE : *ExistTargetPolygonGroupID;
if (MatchTargetPolygonGroupID == INDEX_NONE)
{
MatchTargetPolygonGroupID = TargetMesh.CreatePolygonGroup();
//use the material name to fill the imported material name. Material name will be unique
TargetPolygonGroupImportedMaterialSlotNames[MatchTargetPolygonGroupID] = MaterialUseBySection->GetFName();
ImposterMaterialToPolygonGroupID.Add(MaterialUseBySection, MatchTargetPolygonGroupID);
}
RemapPolygonGroups.Add(SourcePolygonGroupID, MatchTargetPolygonGroupID);
}
});
AppendSettings.bMergeVertexColor = true;
for (int32 ChannelIdx = 0; ChannelIdx < FStaticMeshOperations::FAppendSettings::MAX_NUM_UV_CHANNELS; ++ChannelIdx)
{
AppendSettings.bMergeUVChannels[ChannelIdx] = true;
}
FStaticMeshOperations::AppendMeshDescription(ImposterMesh, InMeshDescription, AppendSettings);
}
}