{"id":14961585,"url":"https://github.com/98teg/spritemesh","last_synced_at":"2025-04-05T04:09:42.965Z","repository":{"id":37572012,"uuid":"401366249","full_name":"98teg/SpriteMesh","owner":"98teg","description":"SpriteMesh is a plugin for Godot that allows you to create 3D meshes based on a 2D sprite.","archived":false,"fork":false,"pushed_at":"2025-03-23T18:39:17.000Z","size":83665,"stargazers_count":164,"open_issues_count":1,"forks_count":11,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-05T04:08:43.167Z","etag":null,"topics":["godot","godot-addon","godot-engine","godot-plugin","godot3","godotengine","mesh-generation","meshes","pixelart","pixelart-game","sprites"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/98teg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-08-30T14:07:24.000Z","updated_at":"2025-04-03T12:09:00.000Z","dependencies_parsed_at":"2024-09-22T13:10:27.394Z","dependency_job_id":null,"html_url":"https://github.com/98teg/SpriteMesh","commit_stats":{"total_commits":23,"total_committers":3,"mean_commits":7.666666666666667,"dds":"0.13043478260869568","last_synced_commit":"a80f8dd2489c8092122a45037db77fda5a5f1e26"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/98teg%2FSpriteMesh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/98teg%2FSpriteMesh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/98teg%2FSpriteMesh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/98teg%2FSpriteMesh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/98teg","download_url":"https://codeload.github.com/98teg/SpriteMesh/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247284949,"owners_count":20913704,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["godot","godot-addon","godot-engine","godot-plugin","godot3","godotengine","mesh-generation","meshes","pixelart","pixelart-game","sprites"],"created_at":"2024-09-24T13:25:44.548Z","updated_at":"2025-04-05T04:09:37.949Z","avatar_url":"https://github.com/98teg.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Sprite Mesh\n\n![Sprite Mesh Banner](./doc/images/sprite_mesh_banner.png)\n\n\u003e **Warning**\n\u003e The main branch of this repository now supports Godot 4.x. If you are looking for the Godot 3.x version, please check [this branch](https://github.com/98teg/SpriteMesh/tree/godot-3.x).\n\n## Introduction\n\nSpriteMesh is a plugin for Godot that allows you to create 3D meshes based on a 2D sprite. It adds two new classes, [`SpriteMesh`](#class-spritemesh) and [`SpriteMeshInstance`](#class-spritemeshinstance). [`SpriteMesh`](#class-spritemesh) is a [`Resource`](https://docs.godotengine.org/en/4.0/classes/class_resource.html) that contains an array of meshes and their material. [`SpriteMeshInstance`](#class-spritemeshinstance), which inherit from [`MeshInstance`](https://docs.godotengine.org/en/stable/classes/class_meshinstance.html?highlight=MeshInstance), is used to create the meshes based on the sprite.\n\n[`SpriteMeshInstance`](#class-spritemeshinstance) can also be used to display the generated meshes on the scene. It has the benefit over [`MeshInstance`](https://docs.godotengine.org/en/stable/classes/class_meshinstance.html?highlight=MeshInstance) in that it adds support for animations in which each frame is a different mesh, as seen in the example below.\n\n![Animation RPG Demo](./doc/images/example_rpg_animation.gif)\n\nThe algorithm [`SpriteMeshInstance`](#class-spritemeshinstance) uses to generate the meshes is a bit demanding. It is for this reason that I do not recommend executing it frequently. However, it has the benefit that the mesh it produces tends to optimize the number of tris. In this image, you can see the result of this algorithm.\n\n![Algorithm Result](./doc/images/result.png)\n\n## How to use it\n\nThere are two ways of using this plugin, via the editor or code. For both of them, you would need to include the folder `sprite_mesh` of this project into the `addons` directory of your Godot project. Then click the `Project` dropdown, select `Project Settings...` and go to the `Plugins` tab. Lastly, click on the `Active` check box at the SpriteMesh row.\n\n### Using the editor\n\nI recommend this method if you don't need to generate the meshes procedurally. Using the editor, the algorithm would not be executed at runtime.\n\n1. Instantiate a [`SpriteMeshInstance`](#class-spritemeshinstance) in your scene.\n2. Assign the texture for your model.\n3. Change any of the properties, if needed. When you change a property, you need to wait three seconds for the editor to update the meshes. This behavior is intended, as it provides a better user experience.\n4. Save or copy the generated mesh if you want to use it in [`MeshInstance`](https://docs.godotengine.org/en/stable/classes/class_meshinstance.html?highlight=MeshInstance) nodes.\n5. Save or copy the generated material if you want to use it in [`MeshInstance`](https://docs.godotengine.org/en/stable/classes/class_meshinstance.html?highlight=MeshInstance) nodes. Remember to make it unique if you reuse this [`SpriteMeshInstance`](#class-spritemeshinstance) to generate other meshes.\n\nIf you want to use animations and pretend to use [`SpriteMeshInstance`](#class-spritemeshinstance) nodes in your scene instead, you can save or copy the [`SpriteMesh`](#class-spritemesh) and assign it to other [`SpriteMeshInstance`](#class-spritemeshinstance) nodes. It is more memory efficient than creating another [`SpriteMeshInstance`](#class-spritemeshinstance) and setting the same texture.\n\n![Editor Usage](./doc/images/editor_usage.png)\n\n### Using code\n\nI recommend this method if you need to generate the meshes procedurally. Bellow is an example of how to create them.\n\n![Code Usage](./doc/images/code_usage.png)\n\nEven if this option is available, I recommend only executing it on methods that are not called frequently, such as `_ready`. If you want to, for example, flip a character sprite, it is better to just rotate the model than changing the [`flip_h`](#bool-flip_h--false) property and regenerating it. The only properties meant to change frequently at runtime are [`frame`](#int-frame--0) and [`frame_coords`](#vector2i-frame_coords--vector2i0-0). And as such, they don't require to call [`update_sprite_mesh`](#void-update_sprite_mesh) to be applied.\n\n## Class `SpriteMesh`\n\n### Description\n\n[`SpriteMesh`](#class-spritemesh) is a [`Resource`](https://docs.godotengine.org/en/4.0/classes/class_resource.html) that contains an array of meshes and their material.\n\n### Properties\n\n|Type|Name|Default value|\n|-|-|-|\n| `StandardMaterial3D` | [`material`](#standardmaterial3d-material) |  |\n| `Array[ArrayMesh]` | [`meshes`](#arrayarraymesh-meshes) | [] |\n\n### Properties Descriptions\n\n#### `StandardMaterial3D material`\n\nThe meshes' material.\n\n```gdscript\nvoid set_material(StandardMaterial3D material)\n\nStandardMaterial3D get_material()\n```\n\n#### `Array[ArrayMesh] meshes`\n\nArray of meshes. Each mesh of the array represents a frame of the animation.\n\n```gdscript\nvoid set_meshes(Array[ArrayMesh] meshes)\n\nArray[ArrayMesh] get_meshes()\n```\n\n## Class `SpriteMeshInstance`\n\n### Description\n\n[`SpriteMeshInstance`](#class-spritemeshinstance), which inherit from [`MeshInstance`](https://docs.godotengine.org/en/stable/classes/class_meshinstance.html?highlight=MeshInstance), is used to create the meshes based on the sprite. It is inspired by [`Sprite3D`](https://docs.godotengine.org/en/4.0/classes/class_sprite3d.html), so many of its properties behave similarly.\n\n### Properties\n\n|Type|Name|Default value|\n|-|-|-|\n| `float` | [`alpha_threshold`](#float-alpha_threshold--00) | `0.0` |\n| `Vector3.Axis` | [`axis`](#vector3axis-axis--2) | `2` |\n| `bool` | [`centered`](#bool-centered--true) | `true` |\n| `float` | [`depth`](#float-depth--10) | `1.0` |\n| `bool` | [`double_sided`](#bool-double_sided--true) | `true` |\n| `bool` | [`flip_h`](#bool-flip_h--false) | `false` |\n| `bool` | [`flip_v`](#bool-flip_v--false) | `false` |\n| `int` | [`frame`](#int-frame--0) | `0` |\n| `Vector2i` | [`frame_coords`](#vector2i-frame_coords--vector2i0-0) | `Vector2i(0, 0)` |\n| `SpriteMesh` | [`generated_sprite_mesh`](#spritemesh-generated_sprite_mesh) |  |\n| `int` | [`hframes`](#int-hframes--1) | `1` |\n| `Vector3` | [`offset`](#vector3-offset--vector30-0) | `Vector2(0, 0)` |\n| `float` | [`pixel_size`](#float-pixel_size--001) | `0.01` |\n| `bool` | [`region_enabled`](#bool-region_enabled--false) | `false` |\n| `Rect2` | [`region_rect`](#rect2-region_rect--rect20-0-0-0) | `Rect2(0, 0, 0, 0)` |\n| `Texture2D` | [`texture`](#texture2d-texture) |  |\n| `float` | [`uv_correction`](#float-uv_correction--00) | `0.0` |\n| `int` | [`vframes`](#int-vframes--1) | `1` |\n\n### Methods\n\n|Returned type|Declaration|\n|-|-|\n|`ArrayMesh`|[`get_mesh_with_index(int index)`](#arraymesh-get_mesh_with_indexint-index)|\n|`void`|[`update_sprite_mesh()`](#void-update_sprite_mesh)|\n\n### Properties Descriptions\n\n#### `float alpha_threshold = 0.0`\n\nThe maximum value of alpha for the algorithm to not render a given pixel.\n\n```gdscript\nvoid set_alpha_threshold(float value)\n\nfloat get_alpha_threshold()\n```\n\n#### `Vector3.Axis axis = 2`\n\nThe direction in which the front of the mesh faces.\n\n```gdscript\nvoid set_axis(Vector3.Axis value)\n\nVector3.Axis get_axis()\n```\n\n#### `bool centered = true`\n\nIf `true`, mesh will be centered.\n\n```gdscript\nvoid set_centered(bool value)\n\nbool is_centered()\n```\n\n#### `float depth = 1.0`\n\nDepth of the mesh, measured in pixels.\n\n```gdscript\nvoid set_depth(float value)\n\nfloat get_depth()\n```\n\n#### `bool double_sided = true`\n\nIf `true`, mesh can be seen from the back as well, if `false`, it is invisible when looking at it from behind.\n\n```gdscript\nvoid set_draw_flag(DrawFlags flag, bool enabled)\n\nbool get_draw_flag(DrawFlags flag)\n```\n\n#### `bool flip_h = false`\n\nIf `true`, mesh is flipped horizontally.\n\n```gdscript\nvoid set_flip_h(bool value)\n\nbool is_flipped_h()\n```\n\n#### `bool flip_v = false`\n\nIf `true`, mesh is flipped vertically.\n\n```gdscript\nvoid set_flip_v(bool value)\n\nbool is_flipped_v()\n```\n\n#### `int frame = 0`\n\nCurrent frame to display from sprite sheet. [`hframes`](#int-hframes--1) or [`vframes`](#int-vframes--1) must be greater than `1`.\n\n```gdscript\nvoid set_frame(int value)\n\nint get_frame()\n```\n\n#### `Vector2i frame_coords = Vector2i(0, 0)`\n\nCoordinates of the frame to display from sprite sheet. This is as an alias for the frame property. [`hframes`](#int-hframes--1) or [`vframes`](#int-vframes--1) must be greater than 1.\n\n```gdscript\nvoid set_frame_coords(Vector2i value)\n\nVector2i get_frame_coords()\n```\n\n#### `SpriteMesh generated_sprite_mesh`\n\nThe result of the algorithm. It would generate automatically in the editor, or after calling [`update_sprite_mesh`](#void-update_sprite_mesh) in code.\n\n```gdscript\nvoid set_generated_sprite_mesh(SpriteMesh value)\n\nSpriteMesh get_generated_sprite_mesh()\n```\n\n#### `int hframes = 1`\n\nThe number of columns in the sprite sheet.\n\n```gdscript\nvoid set_hframes(int value)\n\nint get_hframes()\n```\n\n#### `Vector3 offset = Vector3(0, 0)`\n\nThe mesh's placing offset.\n\n```gdscript\nvoid set_offset(Vector3 value)\n\nVector3 get_offset()\n```\n\n#### `float pixel_size = 0.01`\n\nThe size of one pixel's width on the sprite to scale it in 3D.\n\n```gdscript\nvoid set_pixel_size(float value)\n\nfloat get_pixel_size()\n```\n\n#### `bool region_enabled = false`\n\nIf `true`, the sprite will use [`region_rect`](#rect2-region_rect--rect20-0-0-0) and display only the specified part of its texture.\n\n```gdscript\nvoid set_region_enabled(bool value)\n\nbool is_region_enabled()\n```\n\n#### `Rect2 region_rect = Rect2(0, 0, 0, 0)`\n\nThe region of the atlas texture to display. [`region_enabled`](#bool-region_enabled--false) must be `true`.\n\n```gdscript\nvoid set_region_rect(Rect2 value)\n\nRect2 get_region_rect()\n```\n\n#### `Texture2D texture`\n\nTexture2D object to draw.\n\n```gdscript\nvoid set_texture (Texture2D value)\n\nTexture2D get_texture()\n```\n\n#### `float uv_correction = 0.0`\n\nSometimes, the UV mapping would leak the color of adjacent pixels into parts of the mesh where they shouldn't be. As a result, some lines of color may appear at the border of some faces.\n\nThis property aims to fix this problem. When its value increases, the UV mapping would move inwards. Be careful, as it would also produce misalignment.\n\n```gdscript\nvoid set_uv_correction(float uv_correction)\n\nfloat get_uv_correction()\n```\n\n#### `int vframes = 1`\n\nThe number of rows in the sprite sheet.\n\n```gdscript\nvoid set_vframes(int value)\n\nint get_vframes()\n```\n\n### Method Descriptions\n\n#### `ArrayMesh get_mesh_with_index(int index)`\n\nReturns the mesh that corresponds to a frame of the animation, represented by its index.\n\n#### `void update_sprite_mesh()`\n\nGenerates the meshes and material given the current properties.\n\n## Support\n\nJust give a good ol' star to this GitHub repository if you enjoy this plugin, it means a lot.\n\n## Credits\n\nSprites for the demo project are from [Ninja Adventure](https://pixel-boy.itch.io/ninja-adventure-asset-pack), made by [Pixel-Boy](https://twitter.com/2Pblog1) and [AAA](https://www.instagram.com/challenger.aaa/?hl=fr), check out their work!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F98teg%2Fspritemesh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F98teg%2Fspritemesh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F98teg%2Fspritemesh/lists"}