Facepunch / sbox-sdf

Library providing marching cubes / squares mesh generation
MIT License
15 stars 7 forks source link

Rotated TextureSdfs get offset from their intended position #1

Closed trundlr closed 1 year ago

trundlr commented 1 year ago

In Grubs, we allow players to rotate girders, which are created using TextureSdf.

Currently, applying a rotation to a girder seems to offset the position by an undesired amount. A texture with rotation 0 seems to place in the correct position, however.

Desired Behaviour Since we need to transform a TextureSdf after creating it, it would be nice if the Transform worked appropriately. I also can't help but think it would be nice to be able to just pass into a midpoint into the constructor.

Example

https://github.com/Facepunch/sbox-sdf/assets/57276947/e40b16ec-e958-443d-bec6-dffd3162144b

Code

public void AddTexture( Texture texture, int gradientWidth, float worldWidth, Vector2 position, Rotation2D rotation, Dictionary<Sdf2DMaterial, float> materials )
{
    var textureSdf = new TextureSdf( texture, gradientWidth, worldWidth );
    var transformedTextureSdf = textureSdf.Transform( position, rotation );
    foreach ( var (material, offset) in materials )
        Add( SdfWorld, transformedTextureSdf.Expand( offset ), material );
}
var girderTexture = Texture.Load( FileSystem.Mounted, "textures/texturestamps/girder_sdf.png" );

var terrain = GamemodeSystem.Instance.Terrain;
var materials = new Dictionary<Sdf2DMaterial, float>();
foreach ( var mat in terrain.GetGirderMaterials() )
    materials.Add( mat, 0f );

// Offset mouse position by width and height since the textureWidth passed into the SDF is multiplied by 2.
// This allows the Texture to spawn directly at the player's mouse position.
var position = new Vector2(
    Grub.Player.MousePosition.x - girderTexture.Width,
    Grub.Player.MousePosition.z - girderTexture.Height );

terrain.AddTexture(
    girderTexture,
    4,
    girderTexture.Width * 2,
    position,
    new Rotation2D( RotationAngle ),
    materials );
Metapyziks commented 1 year ago

Oops, didn't see this when I did apetavern/sbox-grubs#242 which demonstrates how to rotate around any point.

I'll add an optional parameter to choose a midpoint / pivot, maybe between (0,0) for the bottom left, and (1,1) for the top-right.

The question is then what would you expect the default to be @trundlr, maybe (0.5, 0.5) for the center?

trundlr commented 1 year ago

Yeah, 0.5, 0.5 makes sense 👍 Thanks again!