Editor helper that builds a single hand-made part (cube, plane, cylinder, cone, wedge, sphere) from a MeshKit, parents it, and tags it with an AmtPart marked as manually created. Used so mapping tools can create props without a generator and leave them untouched on regeneration.
namespace AdvancedMappingTools;
public enum ManualShape
{
Cube,
Plane,
Cylinder,
Cone,
Wedge,
Sphere
}
/// <summary>
/// Objects made by hand. They work with no generator around them, and
/// regeneration never touches them, even when they sit inside a generated building.
/// </summary>
public static class ManualParts
{
const int RoundSides = 16;
public static GameObject Create( ManualShape shape, Vector3 size, Material material, GameObject parent, Transform world )
{
var kit = new MeshKit
{
Material = material
};
var half = size * 0.5f;
switch ( shape )
{
case ManualShape.Plane:
kit.FacingUp( -half.x, half.x, -half.y, half.y, 0.0f );
break;
case ManualShape.Cylinder:
kit.Cylinder( Vector3.Zero, half.x, half.x, -half.z, half.z, RoundSides );
break;
case ManualShape.Cone:
kit.Cylinder( Vector3.Zero, half.x, 0.0f, -half.z, half.z, RoundSides );
break;
case ManualShape.Wedge:
kit.Profile( [new( -half.x, -half.z ), new( half.x, -half.z ), new( -half.x, half.z )], -half.y, half.y );
break;
case ManualShape.Sphere:
var outline = new List<Vector2>();
for ( var i = 0; i <= RoundSides / 2; i++ )
{
var angle = MathF.PI * (i / (float)(RoundSides / 2) - 0.5f);
outline.Add( new Vector2( i == 0 || i == RoundSides / 2 ? 0.0f : MathF.Cos( angle ) * half.x, MathF.Sin( angle ) * half.z ) );
}
kit.Lathe( Vector3.Zero, outline, RoundSides );
break;
default:
kit.Box( -half, half );
break;
}
var go = parent.IsValid() ? new GameObject( parent, true, shape.ToString() ) : new GameObject( true, shape.ToString() );
go.WorldTransform = world;
var mesh = go.Components.Create<MeshComponent>( false );
mesh.Mesh = kit.Finish();
mesh.SmoothingAngle = 40.0f;
mesh.Enabled = true;
var part = go.Components.Create<AmtPart>();
part.PartId = $"manual/{Guid.NewGuid():N}";
part.Kind = $"Manual{shape}";
part.Category = "manual";
part.State = PartState.ManuallyCreated;
part.Dimensions = size;
part.GeneratedTransform = go.LocalTransform;
part.GeneratedGeometry = PartHash.Geometry( mesh.Mesh );
part.GeneratedMaterial = PartHash.Materials( mesh.Mesh );
part.GeneratedFaceMaterials = PartHash.FaceMaterials( mesh.Mesh );
return go;
}
}