├── README.md └── ImplicitSurfacePlugin ├── Resources └── Icon128.png ├── Source └── ImplicitSurfacePlugin │ ├── Public │ ├── ImplicitSurfacePlugin.h │ ├── MetaballMeshComponent.h │ └── ImplicitSurfaceMeshComponent.h │ ├── Private │ ├── ImplicitSurfacePlugin.cpp │ ├── MetaballMeshComponent.cpp │ └── ImplicitSurfaceMeshComponent.cpp │ └── ImplicitSurfacePlugin.Build.cs └── ImplicitSurfacePlugin.uplugin /README.md: -------------------------------------------------------------------------------- 1 | # ImplicitSurfaceComponent 2 | This is a plugin for UE4 to triangulate an implicit surface. 3 | -------------------------------------------------------------------------------- /ImplicitSurfacePlugin/Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NoahZuo/ImplicitSurfaceComponent/HEAD/ImplicitSurfacePlugin/Resources/Icon128.png -------------------------------------------------------------------------------- /ImplicitSurfacePlugin/Source/ImplicitSurfacePlugin/Public/ImplicitSurfacePlugin.h: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "ModuleManager.h" 7 | 8 | class FImplicitSurfacePluginModule : public IModuleInterface 9 | { 10 | public: 11 | 12 | /** IModuleInterface implementation */ 13 | virtual void StartupModule() override; 14 | virtual void ShutdownModule() override; 15 | }; -------------------------------------------------------------------------------- /ImplicitSurfacePlugin/ImplicitSurfacePlugin.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 1, 4 | "VersionName": "1.0", 5 | "FriendlyName": "ImplicitSurfacePlugin", 6 | "Description": "", 7 | "Category": "Other", 8 | "CreatedBy": "Noah Zuo", 9 | "CreatedByURL": "http://blog.csdn.net/noahzuo/", 10 | "DocsURL": "", 11 | "MarketplaceURL": "", 12 | "SupportURL": "", 13 | "CanContainContent": true, 14 | "IsBetaVersion": false, 15 | "Installed": false, 16 | "Modules": [ 17 | { 18 | "Name": "ImplicitSurfacePlugin", 19 | "Type": "Developer", 20 | "LoadingPhase": "Default" 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /ImplicitSurfacePlugin/Source/ImplicitSurfacePlugin/Private/ImplicitSurfacePlugin.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "ImplicitSurfacePlugin.h" 4 | 5 | #define LOCTEXT_NAMESPACE "FImplicitSurfacePluginModule" 6 | 7 | void FImplicitSurfacePluginModule::StartupModule() 8 | { 9 | // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module 10 | } 11 | 12 | void FImplicitSurfacePluginModule::ShutdownModule() 13 | { 14 | // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, 15 | // we call this function before unloading the module. 16 | } 17 | 18 | #undef LOCTEXT_NAMESPACE 19 | 20 | IMPLEMENT_MODULE(FImplicitSurfacePluginModule, ImplicitSurfacePlugin) -------------------------------------------------------------------------------- /ImplicitSurfacePlugin/Source/ImplicitSurfacePlugin/ImplicitSurfacePlugin.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class ImplicitSurfacePlugin : ModuleRules 6 | { 7 | public ImplicitSurfacePlugin(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicIncludePaths.AddRange( 12 | new string[] { 13 | "ImplicitSurfacePlugin/Public" 14 | // ... add public include paths required here ... 15 | } 16 | ); 17 | 18 | 19 | PrivateIncludePaths.AddRange( 20 | new string[] { 21 | "ImplicitSurfacePlugin/Private", 22 | // ... add other private include paths required here ... 23 | } 24 | ); 25 | 26 | 27 | PublicDependencyModuleNames.AddRange( 28 | new string[] 29 | { 30 | "Core", 31 | // ... add other public dependencies that you statically link with here ... 32 | } 33 | ); 34 | 35 | 36 | PrivateDependencyModuleNames.AddRange( 37 | new string[] 38 | { 39 | "CoreUObject", 40 | "Engine", 41 | "Slate", 42 | "SlateCore", 43 | "RHI", 44 | "RenderCore", 45 | "ShaderCore" 46 | // ... add private dependencies that you statically link with here ... 47 | } 48 | ); 49 | 50 | 51 | DynamicallyLoadedModuleNames.AddRange( 52 | new string[] 53 | { 54 | // ... add any modules that your module loads dynamically here ... 55 | } 56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ImplicitSurfacePlugin/Source/ImplicitSurfacePlugin/Private/MetaballMeshComponent.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////// 2 | // 3 | // Copyright (C) 2017 Noah Zuo (noahzuo1994@gmail.com) 4 | // 5 | // This software is provided 'as-is', without any express or implied warranty. 6 | // In no event will the authors be held liable for any damages arising from the use of this software. 7 | // 8 | // Permission is granted to anyone to use this software for any purpose, 9 | // including commercial applications, and to alter it and redistribute it freely, 10 | // subject to the following restrictions: 11 | // 12 | // 1. The origin of this software must not be misrepresented; 13 | // you must not claim that you wrote the original software. 14 | // If you use this software in a product, an acknowledgment 15 | // in the product documentation would be appreciated but is not required. 16 | // 17 | // 2. Altered source versions must be plainly marked as such, 18 | // and must not be misrepresented as being the original software. 19 | // 20 | // 3. This notice may not be removed or altered from any source distribution. 21 | // 22 | //////////////////////////////////////////////////////////// 23 | #include "MetaballMeshComponent.h" 24 | 25 | UMetaballMeshComponent::UMetaballMeshComponent() 26 | { 27 | } 28 | 29 | void UMetaballMeshComponent::ImplicitSurfaceFunction(float x, float y, float z, float& result) 30 | { 31 | float r = 0.0f; 32 | 33 | 34 | for (int i = 0; i < controlPoints.Num(); i++) 35 | { 36 | r += getEquipotentialValue(controlPoints[i], FVector(x, y, z)); 37 | } 38 | 39 | r -= equipotentialValue; 40 | result = r; 41 | } 42 | 43 | float UMetaballMeshComponent::getEquipotentialValue(FControlPoint& controlPoint, FVector p) 44 | { 45 | float sqr = (p - controlPoint.position).SizeSquared(); 46 | float sqrThreshold = controlPoint.threshold*controlPoint.threshold; 47 | if (sqr >= sqrThreshold) 48 | return 0.0f; 49 | else 50 | { 51 | return (controlPoint.scaleFactor * ((sqr / sqrThreshold - 1) * (sqr / sqrThreshold - 1) * (sqr / sqrThreshold - 1) * (sqr / sqrThreshold - 1))); 52 | } 53 | } -------------------------------------------------------------------------------- /ImplicitSurfacePlugin/Source/ImplicitSurfacePlugin/Public/MetaballMeshComponent.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////// 2 | // 3 | // Copyright (C) 2017 Noah Zuo (noahzuo1994@gmail.com) 4 | // 5 | // This software is provided 'as-is', without any express or implied warranty. 6 | // In no event will the authors be held liable for any damages arising from the use of this software. 7 | // 8 | // Permission is granted to anyone to use this software for any purpose, 9 | // including commercial applications, and to alter it and redistribute it freely, 10 | // subject to the following restrictions: 11 | // 12 | // 1. The origin of this software must not be misrepresented; 13 | // you must not claim that you wrote the original software. 14 | // If you use this software in a product, an acknowledgment 15 | // in the product documentation would be appreciated but is not required. 16 | // 17 | // 2. Altered source versions must be plainly marked as such, 18 | // and must not be misrepresented as being the original software. 19 | // 20 | // 3. This notice may not be removed or altered from any source distribution. 21 | // 22 | //////////////////////////////////////////////////////////// 23 | #pragma once 24 | 25 | #include "CoreMinimal.h" 26 | #include "ImplicitSurfaceMeshComponent.h" 27 | #include "MetaballMeshComponent.generated.h" 28 | 29 | USTRUCT(BlueprintType) 30 | struct FControlPoint 31 | { 32 | GENERATED_USTRUCT_BODY() 33 | 34 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Metaball") 35 | FVector position; 36 | 37 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Metaball") 38 | float scaleFactor; 39 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Metaball") 40 | float threshold; 41 | 42 | 43 | FControlPoint() 44 | : position(0, 0, 0) 45 | , scaleFactor(1.0f) 46 | , threshold(1.0f) 47 | { } 48 | }; 49 | 50 | /** 51 | * 52 | */ 53 | UCLASS(editinlinenew, meta = (BlueprintSpawnableComponent)) 54 | class IMPLICITSURFACEPLUGIN_API UMetaballMeshComponent : public UImplicitSurfaceMeshComponent 55 | { 56 | GENERATED_BODY() 57 | public: 58 | UMetaballMeshComponent(); 59 | virtual void ImplicitSurfaceFunction(float x, float y, float z, float& result) override; 60 | 61 | float getEquipotentialValue(FControlPoint& controlPoint, FVector p); 62 | 63 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Metaball") 64 | TArray controlPoints; 65 | 66 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Metaball") 67 | float equipotentialValue; 68 | }; 69 | -------------------------------------------------------------------------------- /ImplicitSurfacePlugin/Source/ImplicitSurfacePlugin/Public/ImplicitSurfaceMeshComponent.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////// 2 | // 3 | // Copyright (C) 2017 Noah Zuo (noahzuo1994@gmail.com) 4 | // 5 | // This software is provided 'as-is', without any express or implied warranty. 6 | // In no event will the authors be held liable for any damages arising from the use of this software. 7 | // 8 | // Permission is granted to anyone to use this software for any purpose, 9 | // including commercial applications, and to alter it and redistribute it freely, 10 | // subject to the following restrictions: 11 | // 12 | // 1. The origin of this software must not be misrepresented; 13 | // you must not claim that you wrote the original software. 14 | // If you use this software in a product, an acknowledgment 15 | // in the product documentation would be appreciated but is not required. 16 | // 17 | // 2. Altered source versions must be plainly marked as such, 18 | // and must not be misrepresented as being the original software. 19 | // 20 | // 3. This notice may not be removed or altered from any source distribution. 21 | // 22 | //////////////////////////////////////////////////////////// 23 | 24 | #pragma once 25 | 26 | #include "CoreMinimal.h" 27 | #include "UObject/ObjectMacros.h" 28 | #include "DynamicMeshBuilder.h" 29 | #include "Components/MeshComponent.h" 30 | #include "ImplicitSurfaceMeshComponent.generated.h" 31 | 32 | /** 33 | * 34 | */ 35 | UCLASS(editinlinenew, meta = (BlueprintSpawnableComponent)) 36 | class IMPLICITSURFACEPLUGIN_API UImplicitSurfaceMeshComponent : public UMeshComponent 37 | { 38 | GENERATED_BODY() 39 | 40 | public: 41 | UImplicitSurfaceMeshComponent(); 42 | static int edgeTable[256]; 43 | static int triTable[256][16]; 44 | 45 | // Begin Component Interface 46 | virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; 47 | virtual void OnRegister() override; 48 | virtual void SendRenderDynamicData_Concurrent() override; 49 | virtual void CreateRenderState_Concurrent() override; 50 | // End Component Interface 51 | 52 | // Begin Property 53 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Grid") 54 | float z_Top = 10.f; 55 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Grid") 56 | float z_Buttom = -10.0f; 57 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Grid") 58 | float x_Left = -10.0f; 59 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Grid") 60 | float x_Right = 10.0f; 61 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Grid") 62 | float y_Front = 10.0f; 63 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Grid") 64 | float y_Back = -10.0f; 65 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Grid") 66 | int subdivision = 10; 67 | 68 | virtual void ImplicitSurfaceFunction(float x, float y, float z, float& result); 69 | 70 | // End Property 71 | 72 | 73 | //~ Begin UPrimitiveComponent Interface. 74 | virtual FPrimitiveSceneProxy* CreateSceneProxy() override; 75 | //~ End UPrimitiveComponent Interface. 76 | 77 | 78 | //~ Begin UMeshComponent Interface. 79 | virtual int32 GetNumMaterials() const override; 80 | //~ End UMeshComponent Interface. 81 | 82 | FCriticalSection m_mutex; 83 | 84 | TArray TriangleVertices; 85 | TArray TriangleIndex; 86 | TArray TriangleNormals; 87 | 88 | 89 | #if WITH_EDITOR 90 | // Begin Debug Interface 91 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Debug") 92 | bool DebugDrawSurface; 93 | private: 94 | void DebugDrawVertices(); 95 | void DebugDrawTriangles(); 96 | // End Debug Interface 97 | #endif 98 | 99 | 100 | 101 | void GenerateMesh(); 102 | void CalculateVerticesFromAGrid(TArray Grid, TArray& Verts, TArray& Triangles, TArray& Normals); 103 | FVector VertexInterp(FVector p1, FVector p2, float densityP1, float densityP2); 104 | 105 | virtual FBoxSphereBounds CalcBounds(const FTransform& LocalToWorld) const override; 106 | friend class FImplicitSurfaceSceneProxy; 107 | 108 | 109 | }; 110 | -------------------------------------------------------------------------------- /ImplicitSurfacePlugin/Source/ImplicitSurfacePlugin/Private/ImplicitSurfaceMeshComponent.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////// 2 | // 3 | // Copyright (C) 2017 Noah Zuo (noahzuo1994@gmail.com) 4 | // 5 | // This software is provided 'as-is', without any express or implied warranty. 6 | // In no event will the authors be held liable for any damages arising from the use of this software. 7 | // 8 | // Permission is granted to anyone to use this software for any purpose, 9 | // including commercial applications, and to alter it and redistribute it freely, 10 | // subject to the following restrictions: 11 | // 12 | // 1. The origin of this software must not be misrepresented; 13 | // you must not claim that you wrote the original software. 14 | // If you use this software in a product, an acknowledgment 15 | // in the product documentation would be appreciated but is not required. 16 | // 17 | // 2. Altered source versions must be plainly marked as such, 18 | // and must not be misrepresented as being the original software. 19 | // 20 | // 3. This notice may not be removed or altered from any source distribution. 21 | // 22 | //////////////////////////////////////////////////////////// 23 | #include "ImplicitSurfaceMeshComponent.h" 24 | #include "Kismet/KismetSystemLibrary.h" 25 | #include "RenderingThread.h" 26 | #include "RenderResource.h" 27 | #include "PrimitiveViewRelevance.h" 28 | #include "PrimitiveSceneProxy.h" 29 | #include "VertexFactory.h" 30 | #include "MaterialShared.h" 31 | #include "Engine/CollisionProfile.h" 32 | #include "Materials/Material.h" 33 | #include "LocalVertexFactory.h" 34 | #include "SceneManagement.h" 35 | #include "EngineGlobals.h" 36 | #include "Engine/Engine.h" 37 | 38 | 39 | struct DynamicImplicitSurfaceMesh 40 | { 41 | TArray points; 42 | TArray normals; 43 | TArray indices; 44 | }; 45 | 46 | 47 | class FImplicitSurfaceVertexBuffer : public FVertexBuffer 48 | { 49 | public: 50 | virtual void InitRHI() override 51 | { 52 | FRHIResourceCreateInfo CreateInfo; 53 | VertexBufferRHI = RHICreateVertexBuffer(NumVerts * sizeof(FDynamicMeshVertex), BUF_Dynamic, CreateInfo); 54 | } 55 | 56 | int32 NumVerts; 57 | }; 58 | 59 | class FImplicitSurfaceIndexBuffer : public FIndexBuffer 60 | { 61 | public: 62 | virtual void InitRHI() override 63 | { 64 | FRHIResourceCreateInfo CreateInfo; 65 | IndexBufferRHI = RHICreateIndexBuffer(sizeof(int32), NumIndices * sizeof(int32), BUF_Dynamic, CreateInfo); 66 | } 67 | 68 | int32 NumIndices; 69 | }; 70 | 71 | class FImplicitSurfaceVertexFactory : public FLocalVertexFactory 72 | { 73 | public: 74 | FImplicitSurfaceVertexFactory() 75 | {} 76 | 77 | /** Initialization */ 78 | void Init(const FImplicitSurfaceVertexBuffer* VertexBuffer) 79 | { 80 | if (IsInRenderingThread()) 81 | { 82 | // Initialize the vertex factory's stream components. 83 | FDataType NewData; 84 | NewData.PositionComponent = STRUCTMEMBER_VERTEXSTREAMCOMPONENT(VertexBuffer, FDynamicMeshVertex, Position, VET_Float3); 85 | NewData.TextureCoordinates.Add( 86 | FVertexStreamComponent(VertexBuffer, STRUCT_OFFSET(FDynamicMeshVertex, TextureCoordinate), sizeof(FDynamicMeshVertex), VET_Float2) 87 | ); 88 | NewData.TangentBasisComponents[0] = STRUCTMEMBER_VERTEXSTREAMCOMPONENT(VertexBuffer, FDynamicMeshVertex, TangentX, VET_PackedNormal); 89 | NewData.TangentBasisComponents[1] = STRUCTMEMBER_VERTEXSTREAMCOMPONENT(VertexBuffer, FDynamicMeshVertex, TangentZ, VET_PackedNormal); 90 | SetData(NewData); 91 | } 92 | else 93 | { 94 | ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER( 95 | InitImplicitSurfaceVertexFactory, 96 | FImplicitSurfaceVertexFactory*, VertexFactory, this, 97 | const FImplicitSurfaceVertexBuffer*, VertexBuffer, VertexBuffer, 98 | { 99 | // Initialize the vertex factory's stream components. 100 | FDataType NewData; 101 | NewData.PositionComponent = STRUCTMEMBER_VERTEXSTREAMCOMPONENT(VertexBuffer,FDynamicMeshVertex,Position,VET_Float3); 102 | NewData.TextureCoordinates.Add( 103 | FVertexStreamComponent(VertexBuffer,STRUCT_OFFSET(FDynamicMeshVertex,TextureCoordinate),sizeof(FDynamicMeshVertex),VET_Float2) 104 | ); 105 | NewData.TangentBasisComponents[0] = STRUCTMEMBER_VERTEXSTREAMCOMPONENT(VertexBuffer,FDynamicMeshVertex,TangentX,VET_PackedNormal); 106 | NewData.TangentBasisComponents[1] = STRUCTMEMBER_VERTEXSTREAMCOMPONENT(VertexBuffer,FDynamicMeshVertex,TangentZ,VET_PackedNormal); 107 | VertexFactory->SetData(NewData); 108 | }); 109 | } 110 | } 111 | 112 | }; 113 | 114 | class FImplicitSurfaceSceneProxy : public FPrimitiveSceneProxy 115 | { 116 | public: 117 | FImplicitSurfaceSceneProxy(UImplicitSurfaceMeshComponent* component) 118 | : FPrimitiveSceneProxy(component) 119 | , DynamicData(nullptr) 120 | , MaterialRelevance(component->GetMaterialRelevance(GetScene().GetFeatureLevel())) 121 | { 122 | // 123 | VerticeNum = component->TriangleVertices.Num(); 124 | IndexNum = component->TriangleIndex.Num() * 3; 125 | 126 | VertexBuffer.NumVerts = VerticeNum; 127 | IndexBuffer.NumIndices = IndexNum; 128 | // Init vertex factory 129 | VertexFactory.Init(&VertexBuffer); 130 | 131 | // Enqueue initialization of render resource 132 | BeginInitResource(&VertexBuffer); 133 | BeginInitResource(&IndexBuffer); 134 | BeginInitResource(&VertexFactory); 135 | 136 | Material = component->GetMaterial(0); 137 | if (Material == NULL) 138 | { 139 | Material = UMaterial::GetDefaultMaterial(MD_Surface); 140 | } 141 | } 142 | 143 | virtual ~FImplicitSurfaceSceneProxy() 144 | { 145 | VertexBuffer.ReleaseResource(); 146 | IndexBuffer.ReleaseResource(); 147 | VertexFactory.ReleaseResource(); 148 | 149 | if (DynamicData != NULL) 150 | { 151 | delete DynamicData; 152 | DynamicData = NULL; 153 | } 154 | } 155 | 156 | void SetDynamicData_RenderThread(DynamicImplicitSurfaceMesh* newData) 157 | { 158 | check(IsInRenderingThread()); 159 | if (DynamicData) 160 | { 161 | delete DynamicData; 162 | DynamicData = NULL; 163 | } 164 | DynamicData = newData; 165 | TArray Vertices; 166 | TArray Indices; 167 | BuildDynamicMesh(DynamicData, Vertices, Indices); 168 | 169 | check(Vertices.Num() == VerticeNum); 170 | check(Indices.Num() == IndexNum); 171 | 172 | void* VertexBufferData = RHILockVertexBuffer(VertexBuffer.VertexBufferRHI, 0, Vertices.Num() * sizeof(FDynamicMeshVertex), RLM_WriteOnly); 173 | FMemory::Memcpy(VertexBufferData, &Vertices[0], Vertices.Num() * sizeof(FDynamicMeshVertex)); 174 | RHIUnlockVertexBuffer(VertexBuffer.VertexBufferRHI); 175 | 176 | void* IndexBufferData = RHILockIndexBuffer(IndexBuffer.IndexBufferRHI, 0, Indices.Num() * sizeof(int32), RLM_WriteOnly); 177 | FMemory::Memcpy(IndexBufferData, &Indices[0], Indices.Num() * sizeof(int32)); 178 | RHIUnlockIndexBuffer(IndexBuffer.IndexBufferRHI); 179 | } 180 | 181 | void BuildDynamicMesh(DynamicImplicitSurfaceMesh* newData, TArray& OutVertices, TArray& OutIndices) 182 | { 183 | OutVertices.Empty(); 184 | OutIndices.Empty(); 185 | 186 | // Process Vertices 187 | for (int i = 0; i < newData->points.Num(); i++) 188 | { 189 | FDynamicMeshVertex newVertex; 190 | newVertex.Position = newData->points[i]; 191 | 192 | /*newVertex.TextureCoordinate.X = 0.0f; 193 | newVertex.TextureCoordinate.Y = 0.0f;*/ 194 | 195 | OutVertices.Add(newVertex); 196 | } 197 | int pointNum = newData->points.Num(); 198 | TArray normalSet; 199 | normalSet.AddZeroed(pointNum); 200 | 201 | 202 | 203 | // Process Triangles 204 | for (int i = 0; i < newData->indices.Num(); i++) 205 | { 206 | OutIndices.Add(newData->indices[i].Z); 207 | OutIndices.Add(newData->indices[i].Y); 208 | OutIndices.Add(newData->indices[i].X); 209 | // Process Normal 210 | FVector Edge01 = (OutVertices[newData->indices[i].Y].Position - 211 | OutVertices[newData->indices[i].X].Position); 212 | 213 | FVector Edge02 = (OutVertices[newData->indices[i].Z].Position - 214 | OutVertices[newData->indices[i].X].Position); 215 | 216 | const FVector TangentX = Edge01.GetSafeNormal(); 217 | const FVector TangentZ = (Edge02 ^ Edge01).GetSafeNormal(); 218 | const FVector TangentY = (TangentX ^ TangentZ).GetSafeNormal(); 219 | 220 | 221 | if (!normalSet[newData->indices[i].X]) 222 | OutVertices[newData->indices[i].X].SetTangents(TangentX, TangentY, TangentZ); 223 | 224 | if (!normalSet[newData->indices[i].Y]) 225 | OutVertices[newData->indices[i].Y].SetTangents(TangentX, TangentY, TangentZ); 226 | 227 | if (!normalSet[newData->indices[i].Z]) 228 | OutVertices[newData->indices[i].Z].SetTangents(TangentX, TangentY, TangentZ); 229 | 230 | } 231 | 232 | } 233 | 234 | virtual void GetDynamicMeshElements(const TArray& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const override 235 | { 236 | QUICK_SCOPE_CYCLE_COUNTER(STAT_ImplicitSurfaceSceneProxy_GetDynamicMeshElements); 237 | 238 | const bool bWireframe = AllowDebugViewmodes() && ViewFamily.EngineShowFlags.Wireframe; 239 | 240 | auto WireframeMaterialInstance = new FColoredMaterialRenderProxy( 241 | GEngine->WireframeMaterial ? GEngine->WireframeMaterial->GetRenderProxy(IsSelected()) : NULL, 242 | FLinearColor(0, 0.5f, 1.f) 243 | ); 244 | 245 | Collector.RegisterOneFrameMaterialProxy(WireframeMaterialInstance); 246 | 247 | FMaterialRenderProxy* MaterialProxy = NULL; 248 | if (bWireframe) 249 | { 250 | MaterialProxy = WireframeMaterialInstance; 251 | } 252 | else 253 | { 254 | MaterialProxy = Material->GetRenderProxy(IsSelected()); 255 | } 256 | 257 | for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) 258 | { 259 | if (VisibilityMap & (1 << ViewIndex)) 260 | { 261 | const FSceneView* View = Views[ViewIndex]; 262 | // Draw the mesh. 263 | FMeshBatch& Mesh = Collector.AllocateMesh(); 264 | FMeshBatchElement& BatchElement = Mesh.Elements[0]; 265 | BatchElement.IndexBuffer = &IndexBuffer; 266 | Mesh.bWireframe = bWireframe; 267 | Mesh.VertexFactory = &VertexFactory; 268 | Mesh.MaterialRenderProxy = MaterialProxy; 269 | BatchElement.PrimitiveUniformBuffer = CreatePrimitiveUniformBufferImmediate(GetLocalToWorld(), GetBounds(), GetLocalBounds(), true, UseEditorDepthTest()); 270 | BatchElement.FirstIndex = 0; 271 | BatchElement.NumPrimitives = IndexBuffer.NumIndices / 3; 272 | BatchElement.MinVertexIndex = 0; 273 | BatchElement.MaxVertexIndex = VertexBuffer.NumVerts - 1; 274 | Mesh.ReverseCulling = IsLocalToWorldDeterminantNegative(); 275 | Mesh.Type = PT_TriangleList; 276 | Mesh.DepthPriorityGroup = SDPG_World; 277 | Mesh.bCanApplyViewModeOverrides = false; 278 | Collector.AddMesh(ViewIndex, Mesh); 279 | 280 | #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) 281 | // Render bounds 282 | RenderBounds(Collector.GetPDI(ViewIndex), ViewFamily.EngineShowFlags, GetBounds(), IsSelected()); 283 | #endif 284 | } 285 | } 286 | } 287 | 288 | virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView* View) const override 289 | { 290 | FPrimitiveViewRelevance Result; 291 | Result.bDrawRelevance = IsShown(View); 292 | Result.bShadowRelevance = IsShadowCast(View); 293 | Result.bDynamicRelevance = true; 294 | MaterialRelevance.SetPrimitiveViewRelevance(Result); 295 | return Result; 296 | } 297 | 298 | virtual uint32 GetMemoryFootprint(void) const override { return(sizeof(*this) + GetAllocatedSize()); } 299 | 300 | uint32 GetAllocatedSize(void) const { return(FPrimitiveSceneProxy::GetAllocatedSize()); } 301 | 302 | virtual bool CanBeOccluded() const override 303 | { 304 | return !MaterialRelevance.bDisableDepthTest; 305 | } 306 | 307 | 308 | private: 309 | UMaterialInterface* Material; 310 | FImplicitSurfaceVertexBuffer VertexBuffer; 311 | FImplicitSurfaceIndexBuffer IndexBuffer; 312 | FImplicitSurfaceVertexFactory VertexFactory; 313 | UImplicitSurfaceMeshComponent* comp; 314 | DynamicImplicitSurfaceMesh* DynamicData; 315 | int VerticeNum; 316 | int IndexNum; 317 | FMaterialRelevance MaterialRelevance; 318 | }; 319 | 320 | UImplicitSurfaceMeshComponent::UImplicitSurfaceMeshComponent() 321 | { 322 | PrimaryComponentTick.bCanEverTick = true; 323 | bTickInEditor = true; 324 | bAutoActivate = true; 325 | TriangleVertices.Empty(); 326 | TriangleIndex.Empty(); 327 | } 328 | 329 | int UImplicitSurfaceMeshComponent::edgeTable[256] = { 330 | 0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, 331 | 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, 332 | 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, 333 | 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, 334 | 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, 335 | 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, 336 | 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, 337 | 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, 338 | 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, 339 | 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, 340 | 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, 341 | 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460, 342 | 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0, 343 | 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230, 344 | 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190, 345 | 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 }; 346 | int UImplicitSurfaceMeshComponent::triTable[256][16] = 347 | { { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 348 | { 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 349 | { 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 350 | { 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 351 | { 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 352 | { 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 353 | { 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 354 | { 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1 }, 355 | { 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 356 | { 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 357 | { 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 358 | { 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1 }, 359 | { 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 360 | { 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1 }, 361 | { 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, 362 | { 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 363 | { 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 364 | { 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 365 | { 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 366 | { 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1 }, 367 | { 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 368 | { 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1 }, 369 | { 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 }, 370 | { 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1 }, 371 | { 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 372 | { 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1 }, 373 | { 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 }, 374 | { 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1 }, 375 | { 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1 }, 376 | { 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1 }, 377 | { 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1 }, 378 | { 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1 }, 379 | { 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 380 | { 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 381 | { 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 382 | { 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1 }, 383 | { 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 384 | { 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, 385 | { 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, 386 | { 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1 }, 387 | { 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 388 | { 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, 389 | { 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 }, 390 | { 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1 }, 391 | { 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1 }, 392 | { 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1 }, 393 | { 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1 }, 394 | { 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1 }, 395 | { 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 396 | { 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1 }, 397 | { 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, 398 | { 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 399 | { 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1 }, 400 | { 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1 }, 401 | { 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1 }, 402 | { 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, 403 | { 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1 }, 404 | { 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1 }, 405 | { 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1 }, 406 | { 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1 }, 407 | { 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1 }, 408 | { 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1 }, 409 | { 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1 }, 410 | { 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 411 | { 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 412 | { 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 413 | { 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 414 | { 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, 415 | { 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 416 | { 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1 }, 417 | { 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, 418 | { 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1 }, 419 | { 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 420 | { 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, 421 | { 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, 422 | { 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1 }, 423 | { 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1 }, 424 | { 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1 }, 425 | { 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1 }, 426 | { 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1 }, 427 | { 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 428 | { 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1 }, 429 | { 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 }, 430 | { 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1 }, 431 | { 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1 }, 432 | { 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1 }, 433 | { 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1 }, 434 | { 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1 }, 435 | { 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, 436 | { 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1 }, 437 | { 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1 }, 438 | { 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1 }, 439 | { 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1 }, 440 | { 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1 }, 441 | { 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1 }, 442 | { 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1 }, 443 | { 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 444 | { 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1 }, 445 | { 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1 }, 446 | { 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1 }, 447 | { 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, 448 | { 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1 }, 449 | { 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 450 | { 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, 451 | { 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1 }, 452 | { 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1 }, 453 | { 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1 }, 454 | { 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1 }, 455 | { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1 }, 456 | { 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1 }, 457 | { 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, 458 | { 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 459 | { 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1 }, 460 | { 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1 }, 461 | { 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1 }, 462 | { 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1 }, 463 | { 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1 }, 464 | { 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1 }, 465 | { 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, 466 | { 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 467 | { 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1 }, 468 | { 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1 }, 469 | { 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1 }, 470 | { 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1 }, 471 | { 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1 }, 472 | { 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 473 | { 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1 }, 474 | { 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 475 | { 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 476 | { 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 477 | { 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 478 | { 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 }, 479 | { 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 480 | { 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 }, 481 | { 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 }, 482 | { 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1 }, 483 | { 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 484 | { 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1 }, 485 | { 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1 }, 486 | { 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1 }, 487 | { 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, 488 | { 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1 }, 489 | { 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1 }, 490 | { 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, 491 | { 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 492 | { 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1 }, 493 | { 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1 }, 494 | { 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1 }, 495 | { 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1 }, 496 | { 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1 }, 497 | { 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1 }, 498 | { 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1 }, 499 | { 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, 500 | { 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 501 | { 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1 }, 502 | { 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1 }, 503 | { 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1 }, 504 | { 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1 }, 505 | { 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1 }, 506 | { 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 507 | { 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 508 | { 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 }, 509 | { 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, 510 | { 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1 }, 511 | { 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, 512 | { 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1 }, 513 | { 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1 }, 514 | { 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1 }, 515 | { 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1 }, 516 | { 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1 }, 517 | { 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1 }, 518 | { 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1 }, 519 | { 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1 }, 520 | { 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1 }, 521 | { 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1 }, 522 | { 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1 }, 523 | { 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1 }, 524 | { 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1 }, 525 | { 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1 }, 526 | { 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1 }, 527 | { 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1 }, 528 | { 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1 }, 529 | { 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1 }, 530 | { 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1 }, 531 | { 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1 }, 532 | { 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, 533 | { 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1 }, 534 | { 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 535 | { 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1 }, 536 | { 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1 }, 537 | { 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 538 | { 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 539 | { 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 540 | { 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1 }, 541 | { 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1 }, 542 | { 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1 }, 543 | { 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1 }, 544 | { 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1 }, 545 | { 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1 }, 546 | { 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1 }, 547 | { 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1 }, 548 | { 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1 }, 549 | { 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1 }, 550 | { 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1 }, 551 | { 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 552 | { 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1 }, 553 | { 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, 554 | { 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 555 | { 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1 }, 556 | { 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1 }, 557 | { 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1 }, 558 | { 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1 }, 559 | { 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1 }, 560 | { 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1 }, 561 | { 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1 }, 562 | { 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 563 | { 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1 }, 564 | { 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1 }, 565 | { 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1 }, 566 | { 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1 }, 567 | { 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1 }, 568 | { 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 569 | { 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1 }, 570 | { 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 571 | { 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, 572 | { 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1 }, 573 | { 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1 }, 574 | { 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1 }, 575 | { 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1 }, 576 | { 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1 }, 577 | { 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1 }, 578 | { 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1 }, 579 | { 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1 }, 580 | { 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1 }, 581 | { 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1 }, 582 | { 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 583 | { 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1 }, 584 | { 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1 }, 585 | { 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 586 | { 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 587 | { 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 588 | { 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1 }, 589 | { 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, 590 | { 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 591 | { 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1 }, 592 | { 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1 }, 593 | { 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 594 | { 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 595 | { 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1 }, 596 | { 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 597 | { 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1 }, 598 | { 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 599 | { 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 600 | { 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 601 | { 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 602 | { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } }; 603 | 604 | 605 | void UImplicitSurfaceMeshComponent::ImplicitSurfaceFunction(float x, float y, float z, float& result) 606 | { 607 | result = (0.25f * (x*x)) + (y * y * 0.25) + (-z); 608 | } 609 | 610 | void UImplicitSurfaceMeshComponent::CalculateVerticesFromAGrid(TArray Grid, TArray& Verts, TArray& Triangles, TArray& Normals) 611 | { 612 | float edgeLengthX = (Grid[1] - Grid[0]).Size(); 613 | float edgeLengthY = (Grid[2] - Grid[1]).Size(); 614 | float edgeLengthZ = (Grid[4] - Grid[0]).Size(); 615 | float densities[8]; 616 | FVector normals[8]; 617 | int CubeIndex = 0; 618 | FVector VertexList[12]; 619 | FVector NormalList[12]; 620 | for (int i = 0; i < Grid.Num(); i++) 621 | { 622 | float density = 0.f; 623 | 624 | ImplicitSurfaceFunction(Grid[i].X, Grid[i].Y, Grid[i].Z, density); 625 | if (density <= 0) 626 | { 627 | CubeIndex |= 1 << i; 628 | } 629 | densities[i] = (density); 630 | 631 | // Process Normal 632 | 633 | float density1, density2; 634 | FVector N; 635 | //GX 636 | ImplicitSurfaceFunction(Grid[i].X + edgeLengthX, Grid[i].Y, Grid[i].Z, density1); 637 | ImplicitSurfaceFunction(Grid[i].X - edgeLengthX, Grid[i].Y, Grid[i].Z, density2); 638 | N.X = (density1 - density2) / edgeLengthX; 639 | 640 | //GY 641 | ImplicitSurfaceFunction(Grid[i].X, Grid[i].Y + edgeLengthY, Grid[i].Z, density1); 642 | ImplicitSurfaceFunction(Grid[i].X, Grid[i].Y - edgeLengthY, Grid[i].Z, density2); 643 | N.Y = (density1 - density2) / edgeLengthY; 644 | 645 | //GZ 646 | ImplicitSurfaceFunction(Grid[i].X, Grid[i].Y, Grid[i].Z + edgeLengthZ, density1); 647 | ImplicitSurfaceFunction(Grid[i].X, Grid[i].Y, Grid[i].Z - edgeLengthZ, density2); 648 | N.Z = (density1 - density2) / edgeLengthZ; 649 | normals[i] = N.GetSafeNormal(); 650 | } 651 | 652 | if (CubeIndex == 0) return; 653 | 654 | //Find the vertices where the surface intersects the cube 655 | if (edgeTable[CubeIndex] & 1) 656 | { 657 | VertexList[0] = 658 | VertexInterp(Grid[0], Grid[1], densities[0], densities[1]); 659 | NormalList[0] = 660 | VertexInterp(normals[0], normals[1], densities[0], densities[1]).GetSafeNormal(); 661 | } 662 | 663 | if (edgeTable[CubeIndex] & 2) 664 | { 665 | VertexList[1] = 666 | VertexInterp(Grid[1], Grid[2], densities[1], densities[2]); 667 | NormalList[1] = 668 | VertexInterp(normals[1], normals[2], densities[1], densities[2]).GetSafeNormal(); 669 | } 670 | 671 | if (edgeTable[CubeIndex] & 4) 672 | { 673 | VertexList[2] = 674 | VertexInterp(Grid[2], Grid[3], densities[2], densities[3]); 675 | NormalList[2] = 676 | VertexInterp(normals[2], normals[3], densities[2], densities[3]).GetSafeNormal(); 677 | } 678 | 679 | if (edgeTable[CubeIndex] & 8) 680 | { 681 | VertexList[3] = 682 | VertexInterp(Grid[3], Grid[0], densities[3], densities[0]); 683 | NormalList[3] = 684 | VertexInterp(normals[3], normals[0], densities[3], densities[0]).GetSafeNormal(); 685 | } 686 | 687 | if (edgeTable[CubeIndex] & 16) 688 | { 689 | VertexList[4] = 690 | VertexInterp(Grid[4], Grid[5], densities[4], densities[5]); 691 | NormalList[4] = 692 | VertexInterp(normals[4], normals[5], densities[4], densities[5]).GetSafeNormal(); 693 | } 694 | 695 | if (edgeTable[CubeIndex] & 32) 696 | { 697 | VertexList[5] = 698 | VertexInterp(Grid[5], Grid[6], densities[5], densities[6]); 699 | NormalList[5] = 700 | VertexInterp(normals[5], normals[6], densities[5], densities[6]).GetSafeNormal(); 701 | } 702 | 703 | if (edgeTable[CubeIndex] & 64) 704 | { 705 | VertexList[6] = 706 | VertexInterp(Grid[6], Grid[7], densities[6], densities[7]); 707 | NormalList[6] = 708 | VertexInterp(normals[6], normals[7], densities[6], densities[7]).GetSafeNormal(); 709 | } 710 | 711 | if (edgeTable[CubeIndex] & 128) 712 | { 713 | VertexList[7] = 714 | VertexInterp(Grid[7], Grid[4], densities[7], densities[4]); 715 | NormalList[7] = 716 | VertexInterp(normals[7], normals[4], densities[7], densities[4]).GetSafeNormal(); 717 | } 718 | 719 | if (edgeTable[CubeIndex] & 256) 720 | { 721 | VertexList[8] = 722 | VertexInterp(Grid[0], Grid[4], densities[0], densities[4]); 723 | NormalList[8] = 724 | VertexInterp(normals[0], normals[4], densities[0], densities[4]).GetSafeNormal(); 725 | } 726 | 727 | if (edgeTable[CubeIndex] & 512) 728 | { 729 | VertexList[9] = 730 | VertexInterp(Grid[1], Grid[5], densities[1], densities[5]); 731 | NormalList[9] = 732 | VertexInterp(normals[1], normals[5], densities[1], densities[5]).GetSafeNormal(); 733 | } 734 | 735 | if (edgeTable[CubeIndex] & 1024) 736 | { 737 | VertexList[10] = 738 | VertexInterp(Grid[2], Grid[6], densities[2], densities[6]); 739 | NormalList[10] = 740 | VertexInterp(normals[2], normals[6], densities[2], densities[6]).GetSafeNormal(); 741 | } 742 | 743 | if (edgeTable[CubeIndex] & 2048) 744 | { 745 | VertexList[11] = 746 | VertexInterp(Grid[3], Grid[7], densities[3], densities[7]); 747 | NormalList[11] = 748 | VertexInterp(normals[3], normals[7], densities[3], densities[7]).GetSafeNormal(); 749 | } 750 | 751 | 752 | int NewVertexCount = 0; 753 | char LocalRemap[12]; 754 | 755 | for (int i = 0; i < 12; i++) 756 | { 757 | LocalRemap[i] = -1; 758 | } 759 | 760 | int originalVertexCount = Verts.Num(); 761 | 762 | // Process vertices 763 | for (int i = 0; triTable[CubeIndex][i] != -1; i++) 764 | { 765 | if (LocalRemap[triTable[CubeIndex][i]] == -1) 766 | { 767 | Verts.Add(VertexList[triTable[CubeIndex][i]]); 768 | Normals.Add(NormalList[triTable[CubeIndex][i]]); 769 | LocalRemap[triTable[CubeIndex][i]] = NewVertexCount; 770 | NewVertexCount++; 771 | } 772 | } 773 | 774 | 775 | // Process Triangles 776 | for (int i = 0; triTable[CubeIndex][i] != -1; i += 3) 777 | { 778 | FIntVector index = FIntVector( 779 | originalVertexCount + LocalRemap[triTable[CubeIndex][i + 0]], 780 | originalVertexCount + LocalRemap[triTable[CubeIndex][i + 1]], 781 | originalVertexCount + LocalRemap[triTable[CubeIndex][i + 2]] 782 | ); 783 | 784 | Triangles.Add(index); 785 | } 786 | 787 | MarkRenderDynamicDataDirty(); 788 | } 789 | 790 | FVector UImplicitSurfaceMeshComponent::VertexInterp(FVector p1, FVector p2, float densityP1, float densityP2) 791 | { 792 | return (p1 + (-densityP1 / (densityP2 - densityP1))*(p2 - p1)); 793 | } 794 | 795 | void UImplicitSurfaceMeshComponent::OnRegister() 796 | { 797 | Super::OnRegister(); 798 | GenerateMesh(); 799 | } 800 | 801 | void UImplicitSurfaceMeshComponent::GenerateMesh() 802 | { 803 | TriangleVertices.Empty(); 804 | TriangleIndex.Empty(); 805 | TriangleNormals.Empty(); 806 | float stepX = (x_Right - x_Left) / subdivision; 807 | for (float x = x_Left; x < x_Right; x += stepX) 808 | { 809 | float stepY = (y_Front - y_Back) / subdivision; 810 | for (float y = y_Back; y < y_Front; y += stepY) 811 | { 812 | float stepZ = (z_Top - z_Buttom) / subdivision; 813 | for (float z = z_Buttom; z < z_Top; z += stepZ) 814 | { 815 | TArray Grid; 816 | Grid.Add(FVector(x, y, z)); 817 | Grid.Add(FVector(x + stepX, y, z)); 818 | Grid.Add(FVector(x + stepX, y + stepY, z)); 819 | Grid.Add(FVector(x, y + stepY, z)); 820 | Grid.Add(FVector(x, y, z + stepZ)); 821 | Grid.Add(FVector(x + stepX, y, z + stepZ)); 822 | Grid.Add(FVector(x + stepX, y + stepY, z + stepZ)); 823 | Grid.Add(FVector(x, y + stepY, z + stepZ)); 824 | 825 | CalculateVerticesFromAGrid(Grid, TriangleVertices, TriangleIndex, TriangleNormals); 826 | } 827 | 828 | } 829 | } 830 | } 831 | 832 | 833 | 834 | FPrimitiveSceneProxy* UImplicitSurfaceMeshComponent::CreateSceneProxy() 835 | { 836 | if (TriangleVertices.Num() == 0) 837 | return nullptr; 838 | 839 | return new FImplicitSurfaceSceneProxy(this); 840 | } 841 | 842 | 843 | int32 UImplicitSurfaceMeshComponent::GetNumMaterials() const 844 | { 845 | return 1; 846 | } 847 | 848 | 849 | 850 | void UImplicitSurfaceMeshComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) 851 | { 852 | Super::TickComponent(DeltaTime, TickType, ThisTickFunction); 853 | 854 | #if WITH_EDITOR 855 | if (DebugDrawSurface) 856 | { 857 | DebugDrawVertices(); 858 | DebugDrawTriangles(); 859 | } 860 | #endif 861 | 862 | } 863 | 864 | void UImplicitSurfaceMeshComponent::CreateRenderState_Concurrent() 865 | { 866 | Super::CreateRenderState_Concurrent(); 867 | SendRenderDynamicData_Concurrent(); 868 | } 869 | 870 | void UImplicitSurfaceMeshComponent::SendRenderDynamicData_Concurrent() 871 | { 872 | if (SceneProxy) 873 | { 874 | DynamicImplicitSurfaceMesh* DynamicData = new DynamicImplicitSurfaceMesh; 875 | DynamicData->indices = TriangleIndex; 876 | DynamicData->points = TriangleVertices; 877 | DynamicData->normals = TriangleNormals; 878 | 879 | // Enqueue command to send to render thread 880 | ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER( 881 | FSendImplicitSurfaceDynamicData, 882 | FImplicitSurfaceSceneProxy*, ImplicitSurfaceSceneProxy, (FImplicitSurfaceSceneProxy*)SceneProxy, 883 | DynamicImplicitSurfaceMesh*, DynamicData, DynamicData, 884 | { 885 | ImplicitSurfaceSceneProxy->SetDynamicData_RenderThread(DynamicData); 886 | }); 887 | } 888 | } 889 | 890 | FBoxSphereBounds UImplicitSurfaceMeshComponent::CalcBounds(const FTransform& LocalToWorld) const 891 | { 892 | 893 | FBox result(ForceInit); 894 | 895 | for (int i = 0; i < TriangleVertices.Num(); i++) 896 | { 897 | result += LocalToWorld.TransformPosition( TriangleVertices[i]); 898 | } 899 | 900 | return FBoxSphereBounds(result); 901 | } 902 | 903 | 904 | 905 | #if WITH_EDITOR 906 | 907 | void UImplicitSurfaceMeshComponent::DebugDrawTriangles() 908 | { 909 | for (int i = 0; i < TriangleIndex.Num(); i++) 910 | { 911 | auto worldPos1 = GetComponentTransform().TransformPosition(TriangleVertices[TriangleIndex[i].X]); 912 | auto worldPos2 = GetComponentTransform().TransformPosition(TriangleVertices[TriangleIndex[i].Y]); 913 | auto worldPos3 = GetComponentTransform().TransformPosition(TriangleVertices[TriangleIndex[i].Z]); 914 | 915 | UKismetSystemLibrary::DrawDebugLine(GetWorld(), worldPos1, worldPos2, FLinearColor::Blue, 1.f); 916 | UKismetSystemLibrary::DrawDebugLine(GetWorld(), worldPos1, worldPos3, FLinearColor::Blue, 1.f); 917 | UKismetSystemLibrary::DrawDebugLine(GetWorld(), worldPos3, worldPos2, FLinearColor::Blue, 1.f); 918 | } 919 | } 920 | void UImplicitSurfaceMeshComponent::DebugDrawVertices() 921 | { 922 | for (int i = 0; i < TriangleVertices.Num(); i++) 923 | { 924 | auto worldPos = GetComponentTransform().TransformPosition(TriangleVertices[i]); 925 | UKismetSystemLibrary::DrawDebugPoint(GetWorld(), worldPos, 1.0f, FLinearColor::Blue, 1.f); 926 | 927 | } 928 | } 929 | 930 | #endif --------------------------------------------------------------------------------