MeshSliceResult.cs
namespace Sandbox;
public sealed class MeshSliceResult
{
public Model UpperModel { get; }
public Model LowerModel { get; }
internal MeshSliceResult( Model upperModel, Model lowerModel )
{
UpperModel = upperModel;
LowerModel = lowerModel;
}
public GameObject CreateUpperHull( GameObject source, string name = "Upper_Hull" )
{
return CreateUpperHull( source, name, autoCopyPhysics: false );
}
public GameObject CreateUpperHull( GameObject source, string name = "Upper_Hull", bool autoCopyPhysics = false )
{
return CreateHullObject( source, UpperModel, name, autoCopyPhysics );
}
public GameObject CreateLowerHull( GameObject source, string name = "Lower_Hull" )
{
return CreateLowerHull( source, name, autoCopyPhysics: false );
}
public GameObject CreateLowerHull( GameObject source, string name = "Lower_Hull", bool autoCopyPhysics = false )
{
return CreateHullObject( source, LowerModel, name, autoCopyPhysics );
}
public GameObject[] CreateHulls( GameObject source, bool disableSource = false, bool autoCopyPhysics = false )
{
var upper = CreateUpperHull( source, autoCopyPhysics: autoCopyPhysics );
var lower = CreateLowerHull( source, autoCopyPhysics: autoCopyPhysics );
if ( disableSource && source is not null )
{
source.Enabled = false;
}
if ( upper is not null && lower is not null )
return new[] { upper, lower };
if ( upper is not null )
return new[] { upper };
if ( lower is not null )
return new[] { lower };
return null;
}
private static GameObject CreateHullObject( GameObject source, Model model, string name, bool autoCopyPhysics )
{
if ( source is null || model is null )
return null;
var newObject = new GameObject( source.Parent, source.Enabled, name );
newObject.WorldTransform = source.WorldTransform;
newObject.Tags.SetFrom( source.Tags );
var sourceRenderer = source.GetComponent<ModelRenderer>( true );
var renderer = newObject.GetOrAddComponent<ModelRenderer>();
renderer.Model = model;
if ( sourceRenderer is not null )
{
renderer.Tint = sourceRenderer.Tint;
renderer.RenderType = sourceRenderer.RenderType;
}
if ( autoCopyPhysics )
{
CopyPhysicsFromSource( source, newObject, model );
}
return newObject;
}
private static void CopyPhysicsFromSource( GameObject source, GameObject destination, Model hullModel )
{
var sourceBody = source.GetComponent<Rigidbody>( true );
if ( sourceBody is not null )
{
var destinationBody = destination.AddComponent<Rigidbody>( false );
CopyRigidbody( sourceBody, destinationBody );
destinationBody.Enabled = sourceBody.Enabled;
}
Collider sourceColliderTemplate = null;
foreach ( var sourceCollider in source.GetComponents<Collider>( true ) )
{
sourceColliderTemplate = sourceCollider;
break;
}
if ( sourceColliderTemplate is not null && hullModel is not null )
{
var destinationCollider = destination.AddComponent<ModelCollider>( false );
CopyCollider( sourceColliderTemplate, destinationCollider );
destinationCollider.Model = hullModel;
destinationCollider.Enabled = sourceColliderTemplate.Enabled;
}
else if ( sourceBody is not null && hullModel is not null )
{
var fallbackCollider = destination.AddComponent<ModelCollider>( false );
fallbackCollider.Model = hullModel;
fallbackCollider.Enabled = sourceBody.Enabled;
}
}
private static void CopyCollider( Collider source, Collider destination )
{
destination.Static = source.Static;
destination.IsTrigger = source.IsTrigger;
destination.Surface = source.Surface;
destination.SurfaceVelocity = source.SurfaceVelocity;
destination.Friction = source.Friction;
destination.Elasticity = source.Elasticity;
destination.RollingResistance = source.RollingResistance;
destination.ColliderFlags = source.ColliderFlags;
}
private static void CopyRigidbody( Rigidbody source, Rigidbody destination )
{
destination.Gravity = source.Gravity;
destination.GravityScale = source.GravityScale;
destination.LinearDamping = source.LinearDamping;
destination.AngularDamping = source.AngularDamping;
destination.MassOverride = source.MassOverride;
destination.OverrideMassCenter = source.OverrideMassCenter;
destination.MassCenterOverride = source.MassCenterOverride;
destination.Locking = source.Locking;
destination.StartAsleep = source.StartAsleep;
destination.RigidbodyFlags = source.RigidbodyFlags;
destination.EnableImpactDamage = source.EnableImpactDamage;
destination.MinImpactDamageSpeed = source.MinImpactDamageSpeed;
destination.ImpactDamage = source.ImpactDamage;
destination.MotionEnabled = source.MotionEnabled;
destination.CollisionEventsEnabled = source.CollisionEventsEnabled;
destination.CollisionUpdateEventsEnabled = source.CollisionUpdateEventsEnabled;
destination.EnhancedCcd = source.EnhancedCcd;
destination.Velocity = source.Velocity;
destination.AngularVelocity = source.AngularVelocity;
}
}