#include "VisceraNodeObject.h" #include "BooleanCutTool.h" #include "FLESHEditor.h" UVisceraNodeObject::UVisceraNodeObject() { // Default values NodeType = TEXT(""); NodeName = NAME_None; DisplayName = TEXT(""); // SoftBody defaults bEnableSimulation = true; GravityStrength = 1.0f; MinFrameSpeed = 0.0f; MaxFrameSpeed = 200.0f; ExternalFrameLerp = 1.0f; InitialGPUInfluence = 0.5f; SubstepTime = 0.01667f; SolverIterations = 1; bRecomputeNormals = true; // Anchor defaults AnchorLocation = FVector::ZeroVector; AnchorRadius = 5.0f; AnchorStiffness = 1.0f; AnchorBoneName = NAME_None; // LineChain defaults LineChainStiffness = 0.5f; LineChainThickness = 1.0f; LineChainPoints.Add(FVector(-10.0f, 0.0f, 0.0f)); LineChainPoints.Add(FVector(10.0f, 0.0f, 0.0f)); // Tetra defaults TetraStiffness = 0.7f; TetraPoints.Add(FVector(0.0f, 0.0f, 0.0f)); TetraPoints.Add(FVector(10.0f, 0.0f, 0.0f)); TetraPoints.Add(FVector(0.0f, 10.0f, 0.0f)); TetraPoints.Add(FVector(0.0f, 0.0f, 10.0f)); // Plane defaults PlaneLocation = FVector::ZeroVector; PlaneNormal = FVector::UpVector; PlaneStiffness = 1.0f; // Cutting defaults bEnableMultiLayerCutting = false; CapMethod = ECapMeshMethod::TriangleFan; } void UVisceraNodeObject::InitFromNodeItem(TSharedPtr InNodeItem) { if (!InNodeItem.IsValid()) { return; } // Basic properties NodeType = InNodeItem->NodeType; NodeName = InNodeItem->NodeName; DisplayName = InNodeItem->DisplayName; // SoftBody properties if (NodeType.Equals(TEXT("SoftBody"))) { bEnableSimulation = InNodeItem->BoolProperties.Contains(TEXT("EnableSimulation")) ? InNodeItem->BoolProperties[TEXT("EnableSimulation")] : true; GravityStrength = InNodeItem->FloatProperties.Contains(TEXT("GravityStrength")) ? InNodeItem->FloatProperties[TEXT("GravityStrength")] : 1.0f; MinFrameSpeed = InNodeItem->FloatProperties.Contains(TEXT("MinFrameSpeed")) ? InNodeItem->FloatProperties[TEXT("MinFrameSpeed")] : 0.0f; MaxFrameSpeed = InNodeItem->FloatProperties.Contains(TEXT("MaxFrameSpeed")) ? InNodeItem->FloatProperties[TEXT("MaxFrameSpeed")] : 200.0f; ExternalFrameLerp = InNodeItem->FloatProperties.Contains(TEXT("ExternalFrameLerp")) ? InNodeItem->FloatProperties[TEXT("ExternalFrameLerp")] : 1.0f; InitialGPUInfluence = InNodeItem->FloatProperties.Contains(TEXT("InitialGPUInfluence")) ? InNodeItem->FloatProperties[TEXT("InitialGPUInfluence")] : 0.5f; SubstepTime = InNodeItem->FloatProperties.Contains(TEXT("SubstepTime")) ? InNodeItem->FloatProperties[TEXT("SubstepTime")] : 0.01667f; SolverIterations = InNodeItem->FloatProperties.Contains(TEXT("SolverIterations")) ? (int32)InNodeItem->FloatProperties[TEXT("SolverIterations")] : 1; bRecomputeNormals = InNodeItem->BoolProperties.Contains(TEXT("RecomputeNormals")) ? InNodeItem->BoolProperties[TEXT("RecomputeNormals")] : true; bEnableMultiLayerCutting = InNodeItem->BoolProperties.Contains(TEXT("EnableMultiLayerCutting")) ? InNodeItem->BoolProperties[TEXT("EnableMultiLayerCutting")] : false; CapMethod = InNodeItem->FloatProperties.Contains(TEXT("CapMethod")) ? (ECapMeshMethod)(int32)InNodeItem->FloatProperties[TEXT("CapMethod")] : ECapMeshMethod::TriangleFan; } // Anchor properties else if (NodeType.Equals(TEXT("Anchor"))) { AnchorRadius = InNodeItem->FloatProperties.Contains(TEXT("Radius")) ? InNodeItem->FloatProperties[TEXT("Radius")] : 5.0f; AnchorStiffness = InNodeItem->FloatProperties.Contains(TEXT("Stiffness")) ? InNodeItem->FloatProperties[TEXT("Stiffness")] : 1.0f; AnchorLocation = InNodeItem->VectorProperties.Contains(TEXT("Location")) ? InNodeItem->VectorProperties[TEXT("Location")] : FVector::ZeroVector; AnchorBoneName = InNodeItem->NameProperties.Contains(TEXT("BoneName")) ? InNodeItem->NameProperties[TEXT("BoneName")] : NAME_None; } // LineChain properties else if (NodeType.Equals(TEXT("LineChain"))) { LineChainStiffness = InNodeItem->FloatProperties.Contains(TEXT("Stiffness")) ? InNodeItem->FloatProperties[TEXT("Stiffness")] : 0.5f; LineChainThickness = InNodeItem->FloatProperties.Contains(TEXT("Thickness")) ? InNodeItem->FloatProperties[TEXT("Thickness")] : 1.0f; LineChainPoints = InNodeItem->PointsArray; if (LineChainPoints.Num() < 2) { LineChainPoints.Add(FVector(-10.0f, 0.0f, 0.0f)); LineChainPoints.Add(FVector(10.0f, 0.0f, 0.0f)); } } // Tetra properties else if (NodeType.Equals(TEXT("Tetra"))) { TetraStiffness = InNodeItem->FloatProperties.Contains(TEXT("Stiffness")) ? InNodeItem->FloatProperties[TEXT("Stiffness")] : 0.7f; TetraPoints = InNodeItem->PointsArray; if (TetraPoints.Num() < 4) { TetraPoints.Empty(); TetraPoints.Add(FVector(0.0f, 0.0f, 0.0f)); TetraPoints.Add(FVector(10.0f, 0.0f, 0.0f)); TetraPoints.Add(FVector(0.0f, 10.0f, 0.0f)); TetraPoints.Add(FVector(0.0f, 0.0f, 10.0f)); } } // Plane properties else if (NodeType.Equals(TEXT("Plane"))) { PlaneStiffness = InNodeItem->FloatProperties.Contains(TEXT("Stiffness")) ? InNodeItem->FloatProperties[TEXT("Stiffness")] : 1.0f; PlaneLocation = InNodeItem->VectorProperties.Contains(TEXT("Location")) ? InNodeItem->VectorProperties[TEXT("Location")] : FVector::ZeroVector; PlaneNormal = InNodeItem->VectorProperties.Contains(TEXT("Normal")) ? InNodeItem->VectorProperties[TEXT("Normal")] : FVector::UpVector; } } void UVisceraNodeObject::ApplyToNodeItem(TSharedPtr InNodeItem) { if (!InNodeItem.IsValid()) { return; } // Basic properties InNodeItem->NodeName = NodeName; InNodeItem->DisplayName = DisplayName; // SoftBody properties if (NodeType.Equals(TEXT("SoftBody"))) { InNodeItem->BoolProperties.Add(TEXT("EnableSimulation"), bEnableSimulation); InNodeItem->FloatProperties.Add(TEXT("GravityStrength"), GravityStrength); InNodeItem->FloatProperties.Add(TEXT("MinFrameSpeed"), MinFrameSpeed); InNodeItem->FloatProperties.Add(TEXT("MaxFrameSpeed"), MaxFrameSpeed); InNodeItem->FloatProperties.Add(TEXT("ExternalFrameLerp"), ExternalFrameLerp); InNodeItem->FloatProperties.Add(TEXT("InitialGPUInfluence"), InitialGPUInfluence); InNodeItem->FloatProperties.Add(TEXT("SubstepTime"), SubstepTime); InNodeItem->FloatProperties.Add(TEXT("SolverIterations"), (float)SolverIterations); InNodeItem->BoolProperties.Add(TEXT("RecomputeNormals"), bRecomputeNormals); InNodeItem->BoolProperties.Add(TEXT("EnableMultiLayerCutting"), bEnableMultiLayerCutting); InNodeItem->FloatProperties.Add(TEXT("CapMethod"), (float)CapMethod); } // Anchor properties else if (NodeType.Equals(TEXT("Anchor"))) { InNodeItem->FloatProperties.Add(TEXT("Radius"), AnchorRadius); InNodeItem->FloatProperties.Add(TEXT("Stiffness"), AnchorStiffness); InNodeItem->VectorProperties.Add(TEXT("Location"), AnchorLocation); InNodeItem->NameProperties.Add(TEXT("BoneName"), AnchorBoneName); } // LineChain properties else if (NodeType.Equals(TEXT("LineChain"))) { InNodeItem->FloatProperties.Add(TEXT("Stiffness"), LineChainStiffness); InNodeItem->FloatProperties.Add(TEXT("Thickness"), LineChainThickness); InNodeItem->PointsArray = LineChainPoints; } // Tetra properties else if (NodeType.Equals(TEXT("Tetra"))) { InNodeItem->FloatProperties.Add(TEXT("Stiffness"), TetraStiffness); InNodeItem->PointsArray = TetraPoints; } // Plane properties else if (NodeType.Equals(TEXT("Plane"))) { InNodeItem->FloatProperties.Add(TEXT("Stiffness"), PlaneStiffness); InNodeItem->VectorProperties.Add(TEXT("Location"), PlaneLocation); InNodeItem->VectorProperties.Add(TEXT("Normal"), PlaneNormal); } }