You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#lockdown Nick.Penwarden #rb none ========================== MAJOR FEATURES + CHANGES ========================== Change 3129636 on 2016/09/17 by Ben.Marsh UBT: Add a "-nolink" option which allows compiling object files without linking them into an executable. Useful for non-unity builds, which take a very long time to link or fail on some platforms due to command lines being too long, PDB file having too many records, etc... Change 3129825 on 2016/09/18 by Ben.Marsh UBT: Don't force Linux to build in unity; it seems to build fine without. Change 3129965 on 2016/09/19 by Matthew.Griffin Duplicating CL#3129960 from Release-4.13 Exclude NetworkProfiler when building CS tools for Linux Change3130653on 2016/09/19 by Ben.Marsh UHT: Fix missing "Error:" prefix in output log, causing messages to be ignored for failure emails. Change3130662on 2016/09/19 by Ben.Marsh EC: Prevent UHT failures from being reported twice, and remove the need for special case to show UHT summary output. Change 3131956 on 2016/09/20 by Matthew.Griffin Addtional fixes for compiling Editor as a monolithic executable Change so monolithic editor is output to Project Binaries directory Removed duplicated ReturnContainerIndexFromChannelName function Only check for out of date modules for non monolithic editor Don't define GIsGameAgnosticExe or PER_MODULE_BOILERPLATE for monolithic editor, done elsewhere Correct IMPLEMENT_MODULE for QuadricMeshReduction and AudioCapture modules Change 3132112 on 2016/09/20 by Ben.Marsh Docs: Remove reference to UBT environment variables from configuration docs. Change 3132815 on 2016/09/20 by Ben.Marsh AutomationTool: Delete GUBP. Everything now uses BuildGraph! Change 3132871 on 2016/09/20 by Ben.Marsh UBT: Remove GUBP callbacks from TargetRules instances. Change 3132987 on 2016/09/20 by Ben.Marsh Allow public distribution of the compiled SimplygonMeshUtilities binaries. Change 3133974 on 2016/09/21 by Ben.Marsh Allow public distribution of the SimplygonSwarm module. Requires a separate Simplygon DLL (still in a NotForLicensees folder) to function correctly. Change 3137228 on 2016/09/22 by Ben.Marsh UAT: Merging fix to parallel executor on Linux from 4.13 branch. Change 3139783 on 2016/09/26 by Matthew.Griffin Fixed Xbox support for Installed Builds Corrected typo in Xbox+PS4 filter creation and added XboxOnePackageNameUtil.exe Added Xbox versions of ThirdParty libs that hadn't been specified until now Change 3141721 on 2016/09/27 by Ben.Marsh Remove declaration of circular references between FbxAutomationTestBuilder and LevelEditor; causes LevelEditor to be built differently if plugin is enabled, which results in shared build products being invalidated by switching between games. Change 3141789 on 2016/09/27 by Ben.Marsh UBT: Retain the ".suppressed" part of output file names when building import libraries for circularly referenced modules. Change 3141805 on 2016/09/27 by Ben.Marsh UBT: Allow reusing build ids in version manifests as long as we aren't modifying any engine binaries (building more or fewer is permitted), and merge manifests together if possible. Allows building the entire solution through Visual Studio, when some projects may build more modules than another. Change 3141980 on 2016/09/27 by Ben.Marsh EC: Include a "Steps to Reproduce" section in failure emails, which gives the command line to run to execute the step. Change 3143996 on 2016/09/28 by Ben.Marsh BuildGraph: Fix exported job steps having dependencies on nodes behind triggers, causing jobs to never terminate. Change 3144696 on 2016/09/29 by Matthew.Griffin Adding -NoSharedPCH to NonUnity build steps and split them into separate nodes for UE4Editor and UE4Game Fixed redefinition of __WINDOWS_DS__ Change 3144931 on 2016/09/29 by Ben.Marsh Core: Changes to search paths for DLL loading. * The default binaries directory is now added to the list of search paths. Normally LoadLibrary finds these without needing to preload them, but plugins can change the global search paths by calling SetDefaultDllDirectories(). * Only the top entry of the DLL directory stack is searched. There is typically only one directory here anyway, but the intent is more consistent with the operation of SetDllDirectory(). * Resolved import paths are converted to absolute, so the resulting calls to LoadLibrary will not be influenced by calls to SetDefaultDllDirectories() changing the base directory. * Search paths aren't de-duplicated any more. They don't overlap in practice, and it's not expensive even if they do. Change 3144932 on 2016/09/29 by Ben.Marsh Vulkan: Only add vulkan-1.dll as a delay load dependency from the VulkanRHI module, otherwise it can be added to the linker command-line 20 or more times. Change 3145011 on 2016/09/29 by Ben.Marsh Core: Include the compatible changelist in version manifests, so local builds after syncing with UGS will have the correct compatible changelist numbers post-hotfix. [CL 3146509 by Ben Marsh in Main branch]
461 lines
13 KiB
C++
461 lines
13 KiB
C++
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "Engine.h"
|
|
#include "RawMesh.h"
|
|
#include "MeshUtilities.h"
|
|
#include "MeshBuild.h"
|
|
|
|
#include "MeshSimplify.h"
|
|
|
|
class FQuadricSimplifierMeshReductionModule : public IMeshReductionModule
|
|
{
|
|
public:
|
|
virtual ~FQuadricSimplifierMeshReductionModule() {}
|
|
|
|
// IModuleInterface interface.
|
|
virtual void StartupModule() override;
|
|
virtual void ShutdownModule() override;
|
|
|
|
// IMeshReductionModule interface.
|
|
virtual class IMeshReduction* GetMeshReductionInterface() override;
|
|
virtual class IMeshMerging* GetMeshMergingInterface() override;
|
|
};
|
|
|
|
|
|
DEFINE_LOG_CATEGORY_STATIC(LogQuadricSimplifier, Log, All);
|
|
IMPLEMENT_MODULE(FQuadricSimplifierMeshReductionModule, QuadricMeshReduction);
|
|
|
|
template< uint32 NumTexCoords >
|
|
class TVertSimp
|
|
{
|
|
typedef TVertSimp< NumTexCoords > VertType;
|
|
public:
|
|
uint32 MaterialIndex;
|
|
FVector Position;
|
|
FVector Normal;
|
|
FVector Tangents[2];
|
|
FLinearColor Color;
|
|
FVector2D TexCoords[ NumTexCoords ];
|
|
|
|
uint32 GetMaterialIndex() const { return MaterialIndex; }
|
|
FVector& GetPos() { return Position; }
|
|
const FVector& GetPos() const { return Position; }
|
|
float* GetAttributes() { return (float*)&Normal; }
|
|
const float* GetAttributes() const { return (const float*)&Normal; }
|
|
|
|
void Correct()
|
|
{
|
|
Normal.Normalize();
|
|
Tangents[0] = Tangents[0] - ( Tangents[0] * Normal ) * Normal;
|
|
Tangents[1] = Tangents[1] - ( Tangents[1] * Normal ) * Normal;
|
|
Tangents[0].Normalize();
|
|
Tangents[1].Normalize();
|
|
Color = Color.GetClamped();
|
|
}
|
|
|
|
bool operator==( const VertType& a ) const
|
|
{
|
|
if( MaterialIndex != a.MaterialIndex ||
|
|
Position != a.Position ||
|
|
Normal != a.Normal ||
|
|
Tangents[0] != a.Tangents[0] ||
|
|
Tangents[1] != a.Tangents[1] ||
|
|
Color != a.Color )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
for( uint32 i = 0; i < NumTexCoords; i++ )
|
|
{
|
|
if( TexCoords[i] != a.TexCoords[i] )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
VertType operator+( const VertType& a ) const
|
|
{
|
|
VertType v;
|
|
v.MaterialIndex = MaterialIndex;
|
|
v.Position = Position + a.Position;
|
|
v.Normal = Normal + a.Normal;
|
|
v.Tangents[0] = Tangents[0] + a.Tangents[0];
|
|
v.Tangents[1] = Tangents[1] + a.Tangents[1];
|
|
v.Color = Color + a.Color;
|
|
|
|
for( uint32 i = 0; i < NumTexCoords; i++ )
|
|
{
|
|
v.TexCoords[i] = TexCoords[i] + a.TexCoords[i];
|
|
}
|
|
return v;
|
|
}
|
|
|
|
VertType operator-( const VertType& a ) const
|
|
{
|
|
VertType v;
|
|
v.MaterialIndex = MaterialIndex;
|
|
v.Position = Position - a.Position;
|
|
v.Normal = Normal - a.Normal;
|
|
v.Tangents[0] = Tangents[0] - a.Tangents[0];
|
|
v.Tangents[1] = Tangents[1] - a.Tangents[1];
|
|
v.Color = Color - a.Color;
|
|
|
|
for( uint32 i = 0; i < NumTexCoords; i++ )
|
|
{
|
|
v.TexCoords[i] = TexCoords[i] - a.TexCoords[i];
|
|
}
|
|
return v;
|
|
}
|
|
|
|
VertType operator*( const float a ) const
|
|
{
|
|
VertType v;
|
|
v.MaterialIndex = MaterialIndex;
|
|
v.Position = Position * a;
|
|
v.Normal = Normal * a;
|
|
v.Tangents[0] = Tangents[0] * a;
|
|
v.Tangents[1] = Tangents[1] * a;
|
|
v.Color = Color * a;
|
|
|
|
for( uint32 i = 0; i < NumTexCoords; i++ )
|
|
{
|
|
v.TexCoords[i] = TexCoords[i] * a;
|
|
}
|
|
return v;
|
|
}
|
|
|
|
VertType operator/( const float a ) const
|
|
{
|
|
float ia = 1.0f / a;
|
|
return (*this) * ia;
|
|
}
|
|
};
|
|
|
|
class FQuadricSimplifierMeshReduction : public IMeshReduction
|
|
{
|
|
public:
|
|
virtual const FString& GetVersionString() const override
|
|
{
|
|
static FString Version = TEXT("1.0");
|
|
return Version;
|
|
}
|
|
|
|
virtual void Reduce(
|
|
FRawMesh& OutReducedMesh,
|
|
float& OutMaxDeviation,
|
|
const FRawMesh& InMesh,
|
|
const TMultiMap<int32, int32>& InOverlappingCorners,
|
|
const FMeshReductionSettings& InSettings
|
|
) override
|
|
{
|
|
IMeshUtilities& MeshUtilities = FModuleManager::Get().LoadModuleChecked<IMeshUtilities>("MeshUtilities");
|
|
|
|
const uint32 NumTexCoords = MAX_STATIC_TEXCOORDS;
|
|
|
|
TArray< TVertSimp< NumTexCoords > > Verts;
|
|
TArray< uint32 > Indexes;
|
|
|
|
TMap< int32, int32 > VertsMap;
|
|
TArray<int32> DupVerts;
|
|
|
|
int32 NumWedges = InMesh.WedgeIndices.Num();
|
|
int32 NumFaces = NumWedges / 3;
|
|
|
|
// Process each face, build vertex buffer and index buffer
|
|
for (int32 FaceIndex = 0; FaceIndex < NumFaces; FaceIndex++)
|
|
{
|
|
FVector Positions[3];
|
|
for (int32 CornerIndex = 0; CornerIndex < 3; CornerIndex++)
|
|
{
|
|
Positions[CornerIndex] = InMesh.VertexPositions[ InMesh.WedgeIndices[ FaceIndex * 3 + CornerIndex ] ];
|
|
}
|
|
|
|
// Don't process degenerate triangles.
|
|
if( PointsEqual( Positions[0], Positions[1] ) ||
|
|
PointsEqual( Positions[0], Positions[2] ) ||
|
|
PointsEqual( Positions[1], Positions[2] ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
int32 VertexIndices[3];
|
|
for (int32 CornerIndex = 0; CornerIndex < 3; CornerIndex++)
|
|
{
|
|
int32 WedgeIndex = FaceIndex * 3 + CornerIndex;
|
|
|
|
TVertSimp< NumTexCoords > NewVert;
|
|
NewVert.MaterialIndex = InMesh.FaceMaterialIndices[ FaceIndex ];
|
|
NewVert.Position = Positions[ CornerIndex ];
|
|
NewVert.Tangents[0] = InMesh.WedgeTangentX[ WedgeIndex ];
|
|
NewVert.Tangents[1] = InMesh.WedgeTangentY[ WedgeIndex ];
|
|
NewVert.Normal = InMesh.WedgeTangentZ[ WedgeIndex ];
|
|
|
|
// Fix bad tangents
|
|
NewVert.Tangents[0] = NewVert.Tangents[0].ContainsNaN() ? FVector::ZeroVector : NewVert.Tangents[0];
|
|
NewVert.Tangents[1] = NewVert.Tangents[1].ContainsNaN() ? FVector::ZeroVector : NewVert.Tangents[1];
|
|
NewVert.Normal = NewVert.Normal.ContainsNaN() ? FVector::ZeroVector : NewVert.Normal;
|
|
|
|
if( InMesh.WedgeColors.Num() == NumWedges )
|
|
{
|
|
NewVert.Color = FLinearColor::FromSRGBColor( InMesh.WedgeColors[ WedgeIndex ] );
|
|
}
|
|
else
|
|
{
|
|
NewVert.Color = FLinearColor::Transparent;
|
|
}
|
|
|
|
for( int32 UVIndex = 0; UVIndex < NumTexCoords; UVIndex++ )
|
|
{
|
|
if( InMesh.WedgeTexCoords[ UVIndex ].Num() == NumWedges )
|
|
{
|
|
NewVert.TexCoords[ UVIndex ] = InMesh.WedgeTexCoords[ UVIndex ][ WedgeIndex ];
|
|
}
|
|
else
|
|
{
|
|
NewVert.TexCoords[ UVIndex ] = FVector2D::ZeroVector;
|
|
}
|
|
}
|
|
|
|
|
|
DupVerts.Reset();
|
|
InOverlappingCorners.MultiFind( WedgeIndex, DupVerts );
|
|
DupVerts.Sort();
|
|
|
|
int32 Index = INDEX_NONE;
|
|
for (int32 k = 0; k < DupVerts.Num(); k++)
|
|
{
|
|
if( DupVerts[k] >= WedgeIndex )
|
|
{
|
|
// the verts beyond me haven't been placed yet, so these duplicates are not relevant
|
|
break;
|
|
}
|
|
|
|
int32* Location = VertsMap.Find( DupVerts[k] );
|
|
if( Location )
|
|
{
|
|
TVertSimp< NumTexCoords >& FoundVert = Verts[ *Location ];
|
|
|
|
if( NewVert.MaterialIndex != FoundVert.MaterialIndex ||
|
|
!PointsEqual( NewVert.Position, FoundVert.Position ) ||
|
|
!NormalsEqual( NewVert.Tangents[0], FoundVert.Tangents[0] ) ||
|
|
!NormalsEqual( NewVert.Tangents[1], FoundVert.Tangents[1] ) ||
|
|
!NormalsEqual( NewVert.Normal, FoundVert.Normal ) ||
|
|
NewVert.Color != FoundVert.Color )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// UVs
|
|
bool bMatch = true;
|
|
for( int32 UVIndex = 0; UVIndex < NumTexCoords; UVIndex++ )
|
|
{
|
|
if( !UVsEqual( NewVert.TexCoords[ UVIndex ], FoundVert.TexCoords[ UVIndex ] ) )
|
|
{
|
|
bMatch = false;
|
|
}
|
|
}
|
|
|
|
if( bMatch )
|
|
{
|
|
Index = *Location;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if( Index == INDEX_NONE )
|
|
{
|
|
Index = Verts.Add( NewVert );
|
|
VertsMap.Add( WedgeIndex, Index );
|
|
}
|
|
VertexIndices[ CornerIndex ] = Index;
|
|
}
|
|
|
|
// Reject degenerate triangles.
|
|
if( VertexIndices[0] == VertexIndices[1] ||
|
|
VertexIndices[1] == VertexIndices[2] ||
|
|
VertexIndices[0] == VertexIndices[2] )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Indexes.Add( VertexIndices[0] );
|
|
Indexes.Add( VertexIndices[1] );
|
|
Indexes.Add( VertexIndices[2] );
|
|
}
|
|
|
|
uint32 NumVerts = Verts.Num();
|
|
uint32 NumIndexes = Indexes.Num();
|
|
uint32 NumTris = NumIndexes / 3;
|
|
|
|
static_assert( NumTexCoords == 8, "NumTexCoords changed, fix AttributeWeights" );
|
|
const uint32 NumAttributes = ( sizeof( TVertSimp< NumTexCoords > ) - sizeof( uint32 ) - sizeof( FVector ) ) / sizeof(float);
|
|
float AttributeWeights[] =
|
|
{
|
|
16.0f, 16.0f, 16.0f, // Normal
|
|
0.1f, 0.1f, 0.1f, // Tangent[0]
|
|
0.1f, 0.1f, 0.1f, // Tangent[1]
|
|
0.1f, 0.1f, 0.1f, 0.1f, // Color
|
|
0.5f, 0.5f, // TexCoord[0]
|
|
0.5f, 0.5f, // TexCoord[1]
|
|
0.5f, 0.5f, // TexCoord[2]
|
|
0.5f, 0.5f, // TexCoord[3]
|
|
0.5f, 0.5f, // TexCoord[4]
|
|
0.5f, 0.5f, // TexCoord[5]
|
|
0.5f, 0.5f, // TexCoord[6]
|
|
0.5f, 0.5f, // TexCoord[7]
|
|
};
|
|
float* ColorWeights = AttributeWeights + 3 + 3 + 3;
|
|
float* TexCoordWeights = ColorWeights + 4;
|
|
|
|
// Zero out weights that aren't used
|
|
{
|
|
if( InMesh.WedgeColors.Num() != NumWedges )
|
|
{
|
|
ColorWeights[0] = 0.0f;
|
|
ColorWeights[1] = 0.0f;
|
|
ColorWeights[2] = 0.0f;
|
|
ColorWeights[3] = 0.0f;
|
|
}
|
|
|
|
for( int32 TexCoordIndex = 0; TexCoordIndex < NumTexCoords; TexCoordIndex++ )
|
|
{
|
|
if( InMesh.WedgeTexCoords[ TexCoordIndex ].Num() != NumWedges )
|
|
{
|
|
TexCoordWeights[ 2 * TexCoordIndex + 0 ] = 0.0f;
|
|
TexCoordWeights[ 2 * TexCoordIndex + 1 ] = 0.0f;
|
|
}
|
|
}
|
|
}
|
|
|
|
TMeshSimplifier< TVertSimp< NumTexCoords >, NumAttributes >* MeshSimp = new TMeshSimplifier< TVertSimp< NumTexCoords >, NumAttributes >( Verts.GetData(), NumVerts, Indexes.GetData(), NumIndexes );
|
|
|
|
MeshSimp->SetAttributeWeights( AttributeWeights );
|
|
//MeshSimp->SetBoundaryLocked();
|
|
MeshSimp->InitCosts();
|
|
|
|
float MaxErrorSqr = MeshSimp->SimplifyMesh( MAX_FLT, NumTris * InSettings.PercentTriangles );
|
|
|
|
NumVerts = MeshSimp->GetNumVerts();
|
|
NumTris = MeshSimp->GetNumTris();
|
|
NumIndexes = NumTris * 3;
|
|
|
|
MeshSimp->OutputMesh( Verts.GetData(), Indexes.GetData() );
|
|
delete MeshSimp;
|
|
|
|
OutMaxDeviation = FMath::Sqrt( MaxErrorSqr ) / 8.0f;
|
|
|
|
{
|
|
// Output FRawMesh
|
|
OutReducedMesh.VertexPositions.Empty( NumVerts );
|
|
OutReducedMesh.VertexPositions.AddUninitialized( NumVerts );
|
|
for( uint32 i= 0; i < NumVerts; i++ )
|
|
{
|
|
OutReducedMesh.VertexPositions[i] = Verts[i].Position;
|
|
}
|
|
|
|
OutReducedMesh.WedgeIndices.Empty( NumIndexes );
|
|
OutReducedMesh.WedgeIndices.AddUninitialized( NumIndexes );
|
|
|
|
for( uint32 i = 0; i < NumIndexes; i++ )
|
|
{
|
|
OutReducedMesh.WedgeIndices[i] = Indexes[i];
|
|
}
|
|
|
|
OutReducedMesh.WedgeTangentX.Empty( NumIndexes );
|
|
OutReducedMesh.WedgeTangentY.Empty( NumIndexes );
|
|
OutReducedMesh.WedgeTangentZ.Empty( NumIndexes );
|
|
OutReducedMesh.WedgeTangentX.AddUninitialized( NumIndexes );
|
|
OutReducedMesh.WedgeTangentY.AddUninitialized( NumIndexes );
|
|
OutReducedMesh.WedgeTangentZ.AddUninitialized( NumIndexes );
|
|
for( uint32 i= 0; i < NumIndexes; i++ )
|
|
{
|
|
OutReducedMesh.WedgeTangentX[i] = Verts[ Indexes[i] ].Tangents[0];
|
|
OutReducedMesh.WedgeTangentY[i] = Verts[ Indexes[i] ].Tangents[1];
|
|
OutReducedMesh.WedgeTangentZ[i] = Verts[ Indexes[i] ].Normal;
|
|
}
|
|
|
|
if( InMesh.WedgeColors.Num() == NumWedges )
|
|
{
|
|
OutReducedMesh.WedgeColors.Empty( NumIndexes );
|
|
OutReducedMesh.WedgeColors.AddUninitialized( NumIndexes );
|
|
for( uint32 i= 0; i < NumIndexes; i++ )
|
|
{
|
|
OutReducedMesh.WedgeColors[i] = Verts[ Indexes[i] ].Color.ToFColor(true);
|
|
}
|
|
}
|
|
|
|
for( int32 TexCoordIndex = 0; TexCoordIndex < NumTexCoords; TexCoordIndex++ )
|
|
{
|
|
if( InMesh.WedgeTexCoords[ TexCoordIndex ].Num() == NumWedges )
|
|
{
|
|
OutReducedMesh.WedgeTexCoords[ TexCoordIndex ].Empty( NumIndexes );
|
|
OutReducedMesh.WedgeTexCoords[ TexCoordIndex ].AddUninitialized( NumIndexes );
|
|
for( uint32 i= 0; i < NumIndexes; i++ )
|
|
{
|
|
OutReducedMesh.WedgeTexCoords[ TexCoordIndex ][i] = Verts[ Indexes[i] ].TexCoords[ TexCoordIndex ];
|
|
}
|
|
}
|
|
}
|
|
|
|
OutReducedMesh.FaceMaterialIndices.Empty( NumTris );
|
|
OutReducedMesh.FaceMaterialIndices.AddUninitialized( NumTris );
|
|
for( uint32 i= 0; i < NumTris; i++ )
|
|
{
|
|
OutReducedMesh.FaceMaterialIndices[i] = Verts[ Indexes[3*i] ].MaterialIndex;
|
|
}
|
|
|
|
OutReducedMesh.FaceSmoothingMasks.Empty( NumTris );
|
|
OutReducedMesh.FaceSmoothingMasks.AddZeroed( NumTris );
|
|
|
|
Verts.Empty();
|
|
Indexes.Empty();
|
|
}
|
|
}
|
|
|
|
virtual bool ReduceSkeletalMesh(
|
|
USkeletalMesh* SkeletalMesh,
|
|
int32 LODIndex,
|
|
const FSkeletalMeshOptimizationSettings& Settings,
|
|
bool bCalcLODDistance,
|
|
bool bReregisterComponent = true
|
|
) override
|
|
{
|
|
return false;
|
|
}
|
|
|
|
virtual bool IsSupported() const override
|
|
{
|
|
return true;
|
|
}
|
|
|
|
virtual ~FQuadricSimplifierMeshReduction() {}
|
|
|
|
static FQuadricSimplifierMeshReduction* Create()
|
|
{
|
|
return new FQuadricSimplifierMeshReduction;
|
|
}
|
|
};
|
|
TScopedPointer<FQuadricSimplifierMeshReduction> GQuadricSimplifierMeshReduction;
|
|
|
|
void FQuadricSimplifierMeshReductionModule::StartupModule()
|
|
{
|
|
GQuadricSimplifierMeshReduction = FQuadricSimplifierMeshReduction::Create();
|
|
}
|
|
|
|
void FQuadricSimplifierMeshReductionModule::ShutdownModule()
|
|
{
|
|
GQuadricSimplifierMeshReduction = NULL;
|
|
}
|
|
|
|
IMeshReduction* FQuadricSimplifierMeshReductionModule::GetMeshReductionInterface()
|
|
{
|
|
return GQuadricSimplifierMeshReduction;
|
|
}
|
|
|
|
IMeshMerging* FQuadricSimplifierMeshReductionModule::GetMeshMergingInterface()
|
|
{
|
|
return NULL;
|
|
}
|