├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── addons
└── quick_place
│ ├── plugin.cfg
│ ├── plugin.gd
│ └── plugin.gd.uid
├── demo
├── materials
│ ├── mat_demo_grounds.tres
│ └── mat_demo_object.tres
├── models
│ ├── demo_grounds.blend
│ ├── demo_grounds.glb
│ ├── demo_grounds.glb.import
│ ├── demo_grounds.tscn
│ ├── demo_object_chair.blend
│ ├── demo_object_chair.glb
│ ├── demo_object_chair.glb.import
│ ├── demo_object_chair.tscn
│ ├── demo_object_cube.blend
│ ├── demo_object_cube.glb
│ ├── demo_object_cube.glb.import
│ ├── demo_object_cube.tscn
│ ├── demo_object_multishape.blend
│ ├── demo_object_multishape.blend1
│ ├── demo_object_multishape.glb
│ ├── demo_object_multishape.glb.import
│ ├── demo_object_multishape.tscn
│ ├── demo_object_sphere.blend
│ ├── demo_object_sphere.glb
│ ├── demo_object_sphere.glb.import
│ ├── demo_object_sphere.tscn
│ ├── demo_object_tree.blend
│ ├── demo_object_tree.blend1
│ ├── demo_object_tree.glb
│ ├── demo_object_tree.glb.import
│ └── demo_object_tree.tscn
└── world.tscn
├── docs
├── demo.webm
├── icon.png
├── icon.png.import
├── icon.svg
├── icon.svg.import
├── screenshot.png
└── screenshot.png.import
├── icon.svg
├── icon.svg.import
└── project.godot
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Normalize EOL for all files that Git considers text files.
2 | * text=auto eol=lf
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Godot 4+ specific ignores
2 | .godot/
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Laura Sofia Heimann
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # QuickPlace
2 | Quickly place packed scenes and optionally rotate towards faces and randomize its position
3 |
4 | 
5 |
6 | ## Features
7 | - **Quickly place PackedScene's**
8 | - Start placement mode and select a Node3D to be used as a parent, then click in your 3D viewport to quickly place your PackedScene.
9 | - **Randomize rotation**
10 | - Randomize the rotation on all axis to quickly scatter objects like rocks
11 | - **Align to Face**
12 | - Align the bottom of the PackedScene to the normal of the face you clicked
13 | - **Random Aligned to Face**
14 | - First, align the bottom of the PackedScene to the normal of the face you clicked. Then, randomize the (local) Y-rotation.
15 |
16 | ## Installation
17 | 1. Download the latest release
18 | 2. Place the ``quick_place`` folder into your ``addons`` folder
19 | 3. Activate the addon
20 |
21 | ## Support
22 | Any version from 4.0 onwards should be compatible. The addon was created and tested with 4.2.2.
23 |
24 | ## Donations
25 | If you would like to support my open source projects, feel free to [drop me a coffee (or rather, an energy drink)](https://ko-fi.com/laurasofiaheimann) or check out my [release games](https://indiegesindel.itch.io) on itch.
26 |
27 | ## License
28 | This project is licensed under the MIT License. For more information, check out the included [LICENSE](LICENSE) file.
--------------------------------------------------------------------------------
/addons/quick_place/plugin.cfg:
--------------------------------------------------------------------------------
1 | [plugin]
2 |
3 | name="QuickPlace"
4 | description="Quickly place packed scenes and optionally rotate towards faces and randomize its position"
5 | author="Laura Sofia Heimann"
6 | version="1.0.0"
7 | script="plugin.gd"
8 |
--------------------------------------------------------------------------------
/addons/quick_place/plugin.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends EditorPlugin
3 |
4 | var dock:Control
5 | var undo_redo:EditorUndoRedoManager = get_undo_redo()
6 |
7 | var setting_scene:PackedScene
8 | var setting_rotation:RotationType
9 | var setting_active:bool
10 |
11 | var start_stop_button:Button
12 |
13 | enum RotationType {
14 | ORIGINAL,
15 | RANDOM,
16 | ALIGNED_TO_FACE,
17 | RANDOM_ALIGNED_TO_FACE,
18 | }
19 |
20 | func _enter_tree()->void:
21 | # Add dock
22 | dock = create_settings_dock()
23 | add_control_to_dock(DOCK_SLOT_RIGHT_BL, dock)
24 |
25 | func _exit_tree()->void:
26 | # Remove dock
27 | remove_control_from_docks(dock)
28 | dock.free()
29 |
30 | func _handles(object:Object)->bool:
31 | return object is Node3D
32 |
33 | func _forward_3d_gui_input(viewport_camera:Camera3D, event:InputEvent)->int:
34 | if not (setting_active and setting_scene != null):
35 | return EditorPlugin.AFTER_GUI_INPUT_PASS
36 | if not (event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed):
37 | return EditorPlugin.AFTER_GUI_INPUT_PASS
38 |
39 | # Raycast mouse
40 | var position_in_node:Vector2 = event.position
41 | var ray_space_state:PhysicsDirectSpaceState3D = viewport_camera.get_world_3d().direct_space_state
42 | var ray_origin:Vector3 = viewport_camera.project_ray_origin(position_in_node)
43 | var ray_end:Vector3 = ray_origin + viewport_camera.project_ray_normal(position_in_node) * 5000.0
44 | var ray_query := PhysicsRayQueryParameters3D.create(ray_origin, ray_end)
45 | ray_query.collide_with_areas = false
46 | var ray_result:Dictionary = ray_space_state.intersect_ray(ray_query)
47 | if not ray_result.has("position"):
48 | return EditorPlugin.AFTER_GUI_INPUT_PASS
49 |
50 | # Instantiate prefab
51 | var parent:Node = get_editor_interface().get_selection().get_selected_nodes()[0]
52 | var prefab:Node3D = setting_scene.instantiate()
53 | prefab.name = str(prefab.name, " #", parent.get_child_count())
54 |
55 | # Place / Unplace
56 | undo_redo.create_action(str("Place ", setting_scene.resource_path))
57 | undo_redo.add_do_method(self, &"place", prefab, parent, ray_result)
58 | undo_redo.add_undo_method(self, &"unplace", prefab, parent)
59 | undo_redo.add_do_reference(prefab)
60 | undo_redo.commit_action()
61 |
62 | return EditorPlugin.AFTER_GUI_INPUT_STOP
63 |
64 | func create_settings_dock()->PanelContainer:
65 | var root := PanelContainer.new()
66 | root.name = "QuickPlace Settings"
67 |
68 | var settings_list := VBoxContainer.new()
69 | settings_list.set_anchors_preset(Control.PRESET_FULL_RECT)
70 | root.add_child(settings_list)
71 |
72 | # SCENE
73 | var scene_picker := EditorResourcePicker.new()
74 | scene_picker.base_type = "PackedScene"
75 | var settings_item_scene:PanelContainer = create_settings_item("Scene", scene_picker)
76 | settings_list.add_child(settings_item_scene)
77 | scene_picker.connect("resource_changed", func(new_resource:PackedScene)->void:
78 | setting_scene = new_resource
79 | start_stop_button.disabled = new_resource == null)
80 |
81 | # ROTATION
82 | var rotation_select := OptionButton.new()
83 | for rotation_type in RotationType:
84 | rotation_select.add_item(rotation_type.capitalize(), RotationType.get(rotation_type))
85 | rotation_select.connect("item_selected", func(index:int)->void:
86 | setting_rotation = index)
87 | var settings_item_rotation_select:PanelContainer = create_settings_item("Rotation", rotation_select)
88 | settings_list.add_child(settings_item_rotation_select)
89 |
90 | # START/STOP BUTTON
91 | start_stop_button = Button.new()
92 | start_stop_button.disabled = true
93 | start_stop_button.text = "Start"
94 | start_stop_button.toggle_mode = true
95 | settings_list.add_child(start_stop_button)
96 | start_stop_button.connect("toggled", func(is_active:bool)->void:
97 | setting_active = is_active
98 | start_stop_button.text = "Stop" if is_active else "Start")
99 |
100 | return root
101 |
102 | func create_settings_item(label:String, control:Control)->PanelContainer:
103 | var new_item_panel := PanelContainer.new()
104 |
105 | var new_item := HBoxContainer.new()
106 | new_item.set_anchors_preset(Control.PRESET_VCENTER_WIDE)
107 | new_item.size_flags_horizontal = Control.SIZE_EXPAND_FILL
108 | new_item_panel.add_child(new_item)
109 |
110 | var new_label := Label.new()
111 | new_label.text = label
112 | new_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
113 | new_item.add_child(new_label)
114 |
115 | control.set_anchors_preset(Control.PRESET_VCENTER_WIDE)
116 | control.size_flags_horizontal = Control.SIZE_EXPAND_FILL
117 | new_item.add_child(control)
118 |
119 | return new_item_panel
120 |
121 | # https://www.reddit.com/r/godot/comments/f2fowu/comment/fhdkxz5/
122 | # Adjusted to support 90° side angles
123 | func align_up(node_basis:Basis, normal:Vector3)->Basis:
124 | var result := Basis()
125 | var scale:Vector3 = node_basis.get_scale()
126 |
127 | # Check if normal is parallel to node_basis.z
128 | if abs(normal.dot(node_basis.z)) > 0.999:
129 | # Choose a different axis to avoid zero vector
130 | if abs(normal.dot(Vector3(1, 0, 0))) < 0.999:
131 | result.x = normal.cross(Vector3(1, 0, 0))
132 | else:
133 | result.x = normal.cross(Vector3(0, 1, 0))
134 | else:
135 | result.x = normal.cross(node_basis.z)
136 |
137 | result.y = normal
138 | result.z = result.x.cross(normal)
139 |
140 | result = result.orthonormalized()
141 | result.x *= scale.x
142 | result.y *= scale.y
143 | result.z *= scale.z
144 |
145 | return result
146 |
147 | func place(prefab:Node3D, parent:Node, ray_result:Dictionary)->void:
148 | # Spawn
149 | parent.add_child(prefab)
150 | prefab.set_owner(parent.get_tree().edited_scene_root)
151 | prefab.global_position = ray_result.position
152 |
153 | # Rotate
154 | match setting_rotation:
155 | RotationType.ALIGNED_TO_FACE, RotationType.RANDOM_ALIGNED_TO_FACE when ray_result.normal != null:
156 | # Align To Face
157 | prefab.global_transform.basis = align_up(prefab.global_transform.basis, ray_result.normal.normalized())
158 |
159 | # Random Aligned To Face
160 | if setting_rotation == RotationType.RANDOM_ALIGNED_TO_FACE:
161 | var random_rotation:float = randf_range(0.0, 360.0)
162 | prefab.global_transform = prefab.global_transform.rotated_local(Vector3.UP, random_rotation)
163 | RotationType.RANDOM:
164 | # Random
165 | var random_rotation_x:float = randf_range(0, TAU)
166 | var random_rotation_y:float = randf_range(0, TAU)
167 | var random_rotation_z:float = randf_range(0, TAU)
168 | prefab.rotation = Vector3(random_rotation_x, random_rotation_y, random_rotation_z)
169 |
170 | func unplace(prefab:Node3D, parent:Node)->void:
171 | parent.remove_child(prefab)
172 |
--------------------------------------------------------------------------------
/addons/quick_place/plugin.gd.uid:
--------------------------------------------------------------------------------
1 | uid://c0ykuu8m3cxlq
2 |
--------------------------------------------------------------------------------
/demo/materials/mat_demo_grounds.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="StandardMaterial3D" format=3 uid="uid://wg2oxm2b06wh"]
2 |
3 | [resource]
4 | resource_name = "Demo"
5 | cull_mode = 2
6 | albedo_color = Color(0.392043, 0.392043, 0.392043, 1)
7 | roughness = 0.5
8 |
--------------------------------------------------------------------------------
/demo/materials/mat_demo_object.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="StandardMaterial3D" format=3 uid="uid://2qmywwner0js"]
2 |
3 | [resource]
4 | resource_name = "Material"
5 | cull_mode = 2
6 | albedo_color = Color(0.906332, 0.906332, 0.906332, 1)
7 | roughness = 0.5
8 |
--------------------------------------------------------------------------------
/demo/models/demo_grounds.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/demo/models/demo_grounds.blend
--------------------------------------------------------------------------------
/demo/models/demo_grounds.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/demo/models/demo_grounds.glb
--------------------------------------------------------------------------------
/demo/models/demo_grounds.glb.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="scene"
4 | importer_version=1
5 | type="PackedScene"
6 | uid="uid://bmu86cnwby5sn"
7 | path="res://.godot/imported/demo_grounds.glb-8344d339b9b3679137553f6d22f6e619.scn"
8 |
9 | [deps]
10 |
11 | source_file="res://demo/models/demo_grounds.glb"
12 | dest_files=["res://.godot/imported/demo_grounds.glb-8344d339b9b3679137553f6d22f6e619.scn"]
13 |
14 | [params]
15 |
16 | nodes/root_type=""
17 | nodes/root_name=""
18 | nodes/apply_root_scale=true
19 | nodes/root_scale=5.0
20 | meshes/ensure_tangents=true
21 | meshes/generate_lods=true
22 | meshes/create_shadow_meshes=true
23 | meshes/light_baking=1
24 | meshes/lightmap_texel_size=0.2
25 | meshes/force_disable_compression=false
26 | skins/use_named_skins=true
27 | animation/import=true
28 | animation/fps=30
29 | animation/trimming=false
30 | animation/remove_immutable_tracks=true
31 | import_script/path=""
32 | _subresources={
33 | "materials": {
34 | "Demo": {
35 | "use_external/enabled": true,
36 | "use_external/path": "res://demo/materials/mat_demo_grounds.tres"
37 | }
38 | },
39 | "nodes": {
40 | "PATH:Elevation": {
41 | "generate/physics": true,
42 | "physics/shape_type": 2
43 | },
44 | "PATH:Roundness": {
45 | "generate/physics": true,
46 | "physics/shape_type": 2
47 | },
48 | "PATH:Slanted": {
49 | "generate/physics": true,
50 | "physics/shape_type": 2
51 | },
52 | "PATH:Sphere": {
53 | "generate/physics": true,
54 | "physics/shape_type": 2
55 | },
56 | "PATH:Uneven": {
57 | "generate/physics": true,
58 | "physics/shape_type": 2
59 | }
60 | }
61 | }
62 | gltf/naming_version=1
63 | gltf/embedded_image_handling=1
64 |
--------------------------------------------------------------------------------
/demo/models/demo_grounds.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://ctr7sx5otsygk"]
2 |
3 | [ext_resource type="PackedScene" uid="uid://bmu86cnwby5sn" path="res://demo/models/demo_grounds.glb" id="1_cepfi"]
4 |
5 | [node name="demo_grounds" instance=ExtResource("1_cepfi")]
6 |
--------------------------------------------------------------------------------
/demo/models/demo_object_chair.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/demo/models/demo_object_chair.blend
--------------------------------------------------------------------------------
/demo/models/demo_object_chair.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/demo/models/demo_object_chair.glb
--------------------------------------------------------------------------------
/demo/models/demo_object_chair.glb.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="scene"
4 | importer_version=1
5 | type="PackedScene"
6 | uid="uid://bkhne30y0sddp"
7 | path="res://.godot/imported/demo_object_chair.glb-4626464ef1b8423c41b8f59297c58659.scn"
8 |
9 | [deps]
10 |
11 | source_file="res://demo/models/demo_object_chair.glb"
12 | dest_files=["res://.godot/imported/demo_object_chair.glb-4626464ef1b8423c41b8f59297c58659.scn"]
13 |
14 | [params]
15 |
16 | nodes/root_type=""
17 | nodes/root_name=""
18 | nodes/apply_root_scale=true
19 | nodes/root_scale=1.0
20 | meshes/ensure_tangents=true
21 | meshes/generate_lods=true
22 | meshes/create_shadow_meshes=true
23 | meshes/light_baking=1
24 | meshes/lightmap_texel_size=0.2
25 | meshes/force_disable_compression=false
26 | skins/use_named_skins=true
27 | animation/import=true
28 | animation/fps=30
29 | animation/trimming=false
30 | animation/remove_immutable_tracks=true
31 | import_script/path=""
32 | _subresources={
33 | "materials": {
34 | "Material": {
35 | "use_external/enabled": true,
36 | "use_external/path": "res://demo/materials/mat_demo_object.tres"
37 | }
38 | },
39 | "nodes": {
40 | "PATH:Cube": {
41 | "generate/physics": true,
42 | "physics/shape_type": 2
43 | }
44 | }
45 | }
46 | gltf/naming_version=1
47 | gltf/embedded_image_handling=1
48 |
--------------------------------------------------------------------------------
/demo/models/demo_object_chair.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://dt3acfy2hqtyx"]
2 |
3 | [ext_resource type="PackedScene" uid="uid://bkhne30y0sddp" path="res://demo/models/demo_object_chair.glb" id="1_m5rw3"]
4 |
5 | [node name="demo_object_chair" instance=ExtResource("1_m5rw3")]
6 |
--------------------------------------------------------------------------------
/demo/models/demo_object_cube.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/demo/models/demo_object_cube.blend
--------------------------------------------------------------------------------
/demo/models/demo_object_cube.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/demo/models/demo_object_cube.glb
--------------------------------------------------------------------------------
/demo/models/demo_object_cube.glb.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="scene"
4 | importer_version=1
5 | type="PackedScene"
6 | uid="uid://d6tpeqscuckp"
7 | path="res://.godot/imported/demo_object_cube.glb-f2cd5312a936712aedb37a6d05243866.scn"
8 |
9 | [deps]
10 |
11 | source_file="res://demo/models/demo_object_cube.glb"
12 | dest_files=["res://.godot/imported/demo_object_cube.glb-f2cd5312a936712aedb37a6d05243866.scn"]
13 |
14 | [params]
15 |
16 | nodes/root_type=""
17 | nodes/root_name=""
18 | nodes/apply_root_scale=true
19 | nodes/root_scale=1.0
20 | meshes/ensure_tangents=true
21 | meshes/generate_lods=true
22 | meshes/create_shadow_meshes=true
23 | meshes/light_baking=1
24 | meshes/lightmap_texel_size=0.2
25 | meshes/force_disable_compression=false
26 | skins/use_named_skins=true
27 | animation/import=true
28 | animation/fps=30
29 | animation/trimming=false
30 | animation/remove_immutable_tracks=true
31 | import_script/path=""
32 | _subresources={
33 | "materials": {
34 | "Material": {
35 | "use_external/enabled": true,
36 | "use_external/path": "res://demo/materials/mat_demo_object.tres"
37 | }
38 | },
39 | "nodes": {
40 | "PATH:Cube": {
41 | "generate/physics": true,
42 | "physics/shape_type": 2
43 | }
44 | }
45 | }
46 | gltf/naming_version=1
47 | gltf/embedded_image_handling=1
48 |
--------------------------------------------------------------------------------
/demo/models/demo_object_cube.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://dtpp8mcwggdbl"]
2 |
3 | [ext_resource type="PackedScene" uid="uid://d6tpeqscuckp" path="res://demo/models/demo_object_cube.glb" id="1_7gunh"]
4 |
5 | [node name="demo_object_cube" instance=ExtResource("1_7gunh")]
6 |
--------------------------------------------------------------------------------
/demo/models/demo_object_multishape.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/demo/models/demo_object_multishape.blend
--------------------------------------------------------------------------------
/demo/models/demo_object_multishape.blend1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/demo/models/demo_object_multishape.blend1
--------------------------------------------------------------------------------
/demo/models/demo_object_multishape.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/demo/models/demo_object_multishape.glb
--------------------------------------------------------------------------------
/demo/models/demo_object_multishape.glb.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="scene"
4 | importer_version=1
5 | type="PackedScene"
6 | uid="uid://1mm5ctl4alef"
7 | path="res://.godot/imported/demo_object_multishape.glb-8cbabae5752d9b4e6295cbfd3184aed6.scn"
8 |
9 | [deps]
10 |
11 | source_file="res://demo/models/demo_object_multishape.glb"
12 | dest_files=["res://.godot/imported/demo_object_multishape.glb-8cbabae5752d9b4e6295cbfd3184aed6.scn"]
13 |
14 | [params]
15 |
16 | nodes/root_type=""
17 | nodes/root_name=""
18 | nodes/apply_root_scale=true
19 | nodes/root_scale=1.0
20 | meshes/ensure_tangents=true
21 | meshes/generate_lods=true
22 | meshes/create_shadow_meshes=true
23 | meshes/light_baking=1
24 | meshes/lightmap_texel_size=0.2
25 | meshes/force_disable_compression=false
26 | skins/use_named_skins=true
27 | animation/import=true
28 | animation/fps=30
29 | animation/trimming=false
30 | animation/remove_immutable_tracks=true
31 | import_script/path=""
32 | _subresources={
33 | "materials": {
34 | "Material": {
35 | "use_external/enabled": true,
36 | "use_external/path": "res://demo/materials/mat_demo_object.tres"
37 | }
38 | },
39 | "nodes": {
40 | "PATH:Cube": {
41 | "generate/physics": true,
42 | "physics/shape_type": 2
43 | },
44 | "PATH:Cube_001": {
45 | "generate/physics": true,
46 | "physics/shape_type": 2
47 | },
48 | "PATH:Cube_002": {
49 | "generate/physics": true,
50 | "physics/shape_type": 2
51 | }
52 | }
53 | }
54 | gltf/naming_version=1
55 | gltf/embedded_image_handling=1
56 |
--------------------------------------------------------------------------------
/demo/models/demo_object_multishape.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://ltprdponfikg"]
2 |
3 | [ext_resource type="PackedScene" uid="uid://1mm5ctl4alef" path="res://demo/models/demo_object_multishape.glb" id="1_0ofw7"]
4 |
5 | [node name="demo_object_multishape" instance=ExtResource("1_0ofw7")]
6 |
--------------------------------------------------------------------------------
/demo/models/demo_object_sphere.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/demo/models/demo_object_sphere.blend
--------------------------------------------------------------------------------
/demo/models/demo_object_sphere.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/demo/models/demo_object_sphere.glb
--------------------------------------------------------------------------------
/demo/models/demo_object_sphere.glb.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="scene"
4 | importer_version=1
5 | type="PackedScene"
6 | uid="uid://da0hc6x1x7i23"
7 | path="res://.godot/imported/demo_object_sphere.glb-baad5c6c2dd3cd7b6c1976d756271531.scn"
8 |
9 | [deps]
10 |
11 | source_file="res://demo/models/demo_object_sphere.glb"
12 | dest_files=["res://.godot/imported/demo_object_sphere.glb-baad5c6c2dd3cd7b6c1976d756271531.scn"]
13 |
14 | [params]
15 |
16 | nodes/root_type=""
17 | nodes/root_name=""
18 | nodes/apply_root_scale=true
19 | nodes/root_scale=1.0
20 | meshes/ensure_tangents=true
21 | meshes/generate_lods=true
22 | meshes/create_shadow_meshes=true
23 | meshes/light_baking=1
24 | meshes/lightmap_texel_size=0.2
25 | meshes/force_disable_compression=false
26 | skins/use_named_skins=true
27 | animation/import=true
28 | animation/fps=30
29 | animation/trimming=false
30 | animation/remove_immutable_tracks=true
31 | import_script/path=""
32 | _subresources={
33 | "materials": {
34 | "Material": {
35 | "use_external/enabled": true,
36 | "use_external/path": "res://demo/materials/mat_demo_object.tres"
37 | }
38 | },
39 | "nodes": {
40 | "PATH:Sphere": {
41 | "generate/physics": true,
42 | "physics/shape_type": 2
43 | }
44 | }
45 | }
46 | gltf/naming_version=1
47 | gltf/embedded_image_handling=1
48 |
--------------------------------------------------------------------------------
/demo/models/demo_object_sphere.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://duxki0x0s8jd2"]
2 |
3 | [ext_resource type="PackedScene" uid="uid://da0hc6x1x7i23" path="res://demo/models/demo_object_sphere.glb" id="1_ljudk"]
4 |
5 | [node name="demo_object_sphere" instance=ExtResource("1_ljudk")]
6 |
--------------------------------------------------------------------------------
/demo/models/demo_object_tree.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/demo/models/demo_object_tree.blend
--------------------------------------------------------------------------------
/demo/models/demo_object_tree.blend1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/demo/models/demo_object_tree.blend1
--------------------------------------------------------------------------------
/demo/models/demo_object_tree.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/demo/models/demo_object_tree.glb
--------------------------------------------------------------------------------
/demo/models/demo_object_tree.glb.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="scene"
4 | importer_version=1
5 | type="PackedScene"
6 | uid="uid://bqsgn5ky4qi1y"
7 | path="res://.godot/imported/demo_object_tree.glb-f7bf2b10e8ed14415851040601ebd42b.scn"
8 |
9 | [deps]
10 |
11 | source_file="res://demo/models/demo_object_tree.glb"
12 | dest_files=["res://.godot/imported/demo_object_tree.glb-f7bf2b10e8ed14415851040601ebd42b.scn"]
13 |
14 | [params]
15 |
16 | nodes/root_type=""
17 | nodes/root_name=""
18 | nodes/apply_root_scale=true
19 | nodes/root_scale=1.0
20 | meshes/ensure_tangents=true
21 | meshes/generate_lods=true
22 | meshes/create_shadow_meshes=true
23 | meshes/light_baking=1
24 | meshes/lightmap_texel_size=0.2
25 | meshes/force_disable_compression=false
26 | skins/use_named_skins=true
27 | animation/import=true
28 | animation/fps=30
29 | animation/trimming=false
30 | animation/remove_immutable_tracks=true
31 | import_script/path=""
32 | _subresources={
33 | "materials": {
34 | "Material": {
35 | "use_external/enabled": true,
36 | "use_external/path": "res://demo/materials/mat_demo_object.tres"
37 | }
38 | },
39 | "nodes": {
40 | "PATH:Cylinder": {
41 | "generate/physics": true,
42 | "physics/shape_type": 2
43 | }
44 | }
45 | }
46 | gltf/naming_version=1
47 | gltf/embedded_image_handling=1
48 |
--------------------------------------------------------------------------------
/demo/models/demo_object_tree.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://ctih8b88r2jb8"]
2 |
3 | [ext_resource type="PackedScene" uid="uid://bqsgn5ky4qi1y" path="res://demo/models/demo_object_tree.glb" id="1_p82h6"]
4 |
5 | [node name="demo_object_tree" instance=ExtResource("1_p82h6")]
6 |
--------------------------------------------------------------------------------
/demo/world.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=3 format=3 uid="uid://cjpigp1c7y5c7"]
2 |
3 | [ext_resource type="PackedScene" uid="uid://ctr7sx5otsygk" path="res://demo/models/demo_grounds.tscn" id="1_50jbj"]
4 |
5 | [sub_resource type="Environment" id="Environment_titps"]
6 | background_mode = 1
7 | background_color = Color(0.817521, 0.817521, 0.817521, 1)
8 |
9 | [node name="World" type="Node3D"]
10 |
11 | [node name="WorldEnvironment" type="WorldEnvironment" parent="."]
12 | environment = SubResource("Environment_titps")
13 |
14 | [node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
15 | transform = Transform3D(0.258819, -0.683013, 0.683013, 0, 0.707107, 0.707107, -0.965926, -0.183013, 0.183013, 0, 23, 0)
16 | shadow_enabled = true
17 |
18 | [node name="Camera3D" type="Camera3D" parent="."]
19 | transform = Transform3D(0.939693, -0.116978, 0.321394, 0, 0.939693, 0.34202, -0.34202, -0.321394, 0.883022, 15.51, 13.84, 21.585)
20 | current = true
21 |
22 | [node name="demo_grounds" parent="." instance=ExtResource("1_50jbj")]
23 |
24 | [node name="objects" type="Node3D" parent="."]
25 |
--------------------------------------------------------------------------------
/docs/demo.webm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/docs/demo.webm
--------------------------------------------------------------------------------
/docs/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/docs/icon.png
--------------------------------------------------------------------------------
/docs/icon.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://dwof00pti2owc"
6 | path="res://.godot/imported/icon.png-be38bcc53a5f19f28a8c043cf1cbb790.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://docs/icon.png"
14 | dest_files=["res://.godot/imported/icon.png-be38bcc53a5f19f28a8c043cf1cbb790.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 |
--------------------------------------------------------------------------------
/docs/icon.svg:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/docs/icon.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://cdadamvd8khln"
6 | path="res://.godot/imported/icon.svg-d74203da674a59f31ae118bcc76df45e.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://docs/icon.svg"
14 | dest_files=["res://.godot/imported/icon.svg-d74203da674a59f31ae118bcc76df45e.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/docs/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LauraWebdev/Godot4-QuickPlace/4944ddc6f0943d7ed5304cd80f7c9af493f7a16d/docs/screenshot.png
--------------------------------------------------------------------------------
/docs/screenshot.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://bakifnp77uta5"
6 | path="res://.godot/imported/screenshot.png-5c854034f77817cfff9777cb4fcabae4.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://docs/screenshot.png"
14 | dest_files=["res://.godot/imported/screenshot.png-5c854034f77817cfff9777cb4fcabae4.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 |
--------------------------------------------------------------------------------
/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/icon.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://xxig72v206oh"
6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://icon.svg"
14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="Addon_QuickPlace"
14 | run/main_scene="res://demo/world.tscn"
15 | config/features=PackedStringArray("4.2", "Forward Plus")
16 | config/icon="res://icon.svg"
17 |
18 | [dotnet]
19 |
20 | project/assembly_name="Addon_QuickPlace"
21 |
22 | [editor_plugins]
23 |
24 | enabled=PackedStringArray("res://addons/quick_place/plugin.cfg")
25 |
--------------------------------------------------------------------------------