commit 11ee2c794999a9477316c715a9e41c172598f874 Author: Lera ElvoƩ Date: Wed May 24 00:27:34 2023 +0300 initial commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4709183 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Godot 4+ specific ignores +.godot/ diff --git a/addons/cyclops_level_builder/actions/action_delete_selected_blocks.gd b/addons/cyclops_level_builder/actions/action_delete_selected_blocks.gd new file mode 100644 index 0000000..66fb6a1 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_delete_selected_blocks.gd @@ -0,0 +1,46 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionDeleteSelectedBlocks +extends CyclopsAction + + +func _init(plugin:CyclopsLevelBuilder, name:String = "", accellerator:Key = KEY_NONE): + super._init(plugin, "Delete Selected Blocks") + +func _execute(): + var blocks:Array[CyclopsConvexBlock] = plugin.get_selected_blocks() + if blocks.is_empty(): + return + + var cmd:CommandDeleteBlocks = CommandDeleteBlocks.new() + cmd.builder = plugin + + for block in blocks: + cmd.block_paths.append(block.get_path()) + + + var undo:EditorUndoRedoManager = plugin.get_undo_redo() + cmd.add_to_undo_manager(undo) + diff --git a/addons/cyclops_level_builder/actions/action_duplicate_selected_blocks.gd b/addons/cyclops_level_builder/actions/action_duplicate_selected_blocks.gd new file mode 100644 index 0000000..8faca53 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_duplicate_selected_blocks.gd @@ -0,0 +1,45 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionDuplicateSelectedBlocks +extends CyclopsAction + + +func _init(plugin:CyclopsLevelBuilder, name:String = "", accellerator:Key = KEY_NONE): + super._init(plugin, "Duplicate Selected Blocks") + +func _execute(): + var blocks:Array[CyclopsConvexBlock] = plugin.get_selected_blocks() + if blocks.is_empty(): + return + + var cmd:CommandDuplicateBlocks = CommandDuplicateBlocks.new() + cmd.builder = plugin + + for block in blocks: + cmd.blocks_to_duplicate.append(block.get_path()) + + + var undo:EditorUndoRedoManager = plugin.get_undo_redo() + cmd.add_to_undo_manager(undo) diff --git a/addons/cyclops_level_builder/actions/action_merge_selected_blocks.gd b/addons/cyclops_level_builder/actions/action_merge_selected_blocks.gd new file mode 100644 index 0000000..e46660d --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_merge_selected_blocks.gd @@ -0,0 +1,45 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionMergeSelectedBlocks +extends CyclopsAction + + +func _init(plugin:CyclopsLevelBuilder, name:String = "", accellerator:Key = KEY_NONE): + super._init(plugin, "Merge Selected Blocks") + +func _execute(): + var blocks:Array[CyclopsConvexBlock] = plugin.get_selected_blocks() + if blocks.is_empty(): + return + + var cmd:CommandMergeBlocks = CommandMergeBlocks.new() + cmd.builder = plugin + + for block in blocks: + cmd.block_paths.append(block.get_path()) + + + var undo:EditorUndoRedoManager = plugin.get_undo_redo() + cmd.add_to_undo_manager(undo) diff --git a/addons/cyclops_level_builder/actions/action_mirror_selection_x.gd b/addons/cyclops_level_builder/actions/action_mirror_selection_x.gd new file mode 100644 index 0000000..5d94e1a --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_mirror_selection_x.gd @@ -0,0 +1,30 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionMirrorSelectionX2 +extends ActionScaleSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Mirror Selection X") + scale = Vector3(-1, 1, 1) diff --git a/addons/cyclops_level_builder/actions/action_mirror_selection_y.gd b/addons/cyclops_level_builder/actions/action_mirror_selection_y.gd new file mode 100644 index 0000000..aa34414 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_mirror_selection_y.gd @@ -0,0 +1,30 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionMirrorSelectionY2 +extends ActionScaleSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Mirror Selection Y") + scale = Vector3(1, -1, 1) diff --git a/addons/cyclops_level_builder/actions/action_mirror_selection_z.gd b/addons/cyclops_level_builder/actions/action_mirror_selection_z.gd new file mode 100644 index 0000000..2f919e6 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_mirror_selection_z.gd @@ -0,0 +1,30 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionMirrorSelectionZ +extends ActionScaleSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Mirror Selection Z") + scale = Vector3(1, 1, -1) diff --git a/addons/cyclops_level_builder/actions/action_rotate_selection.gd b/addons/cyclops_level_builder/actions/action_rotate_selection.gd new file mode 100644 index 0000000..61b9ac5 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_selection.gd @@ -0,0 +1,55 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionRotateSelection +extends CyclopsAction + +var rotation_axis:Vector3 = Vector3.ONE +var rotation_angle:float + +func _init(plugin:CyclopsLevelBuilder, name:String = "", accellerator:Key = KEY_NONE): + super._init(plugin, name, accellerator) + +func _execute(): + var blocks:Array[CyclopsConvexBlock] = plugin.get_selected_blocks() + if blocks.is_empty(): + return + + var pivot:Vector3 = calc_pivot_of_blocks(blocks) + + var cmd:CommandTransformBlocks = CommandTransformBlocks.new() + cmd.builder = plugin + + for block in blocks: + cmd.add_block(block.get_path()) + + var xform:Transform3D = Transform3D.IDENTITY + xform = xform.translated_local(pivot) + xform = xform.rotated_local(rotation_axis, rotation_angle) + xform = xform.translated_local(-pivot) + cmd.transform = xform + #print("cform %s" % xform) + + var undo:EditorUndoRedoManager = plugin.get_undo_redo() + cmd.add_to_undo_manager(undo) diff --git a/addons/cyclops_level_builder/actions/action_rotate_x_180.gd b/addons/cyclops_level_builder/actions/action_rotate_x_180.gd new file mode 100644 index 0000000..5f48b60 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_x_180.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionRotateX180 +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 180 X") + rotation_axis = Vector3(1, 0, 0) + rotation_angle = deg_to_rad(180) diff --git a/addons/cyclops_level_builder/actions/action_rotate_x_90_ccw.gd b/addons/cyclops_level_builder/actions/action_rotate_x_90_ccw.gd new file mode 100644 index 0000000..9bec89a --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_x_90_ccw.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionRotateX90Ccw +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 90 Ccw X") + rotation_axis = Vector3(1, 0, 0) + rotation_angle = deg_to_rad(90) diff --git a/addons/cyclops_level_builder/actions/action_rotate_x_90_cw.gd b/addons/cyclops_level_builder/actions/action_rotate_x_90_cw.gd new file mode 100644 index 0000000..7fe123a --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_x_90_cw.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionRotateX90Cw +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 90 Cw X") + rotation_axis = Vector3(1, 0, 0) + rotation_angle = deg_to_rad(-90) diff --git a/addons/cyclops_level_builder/actions/action_rotate_y_180.gd b/addons/cyclops_level_builder/actions/action_rotate_y_180.gd new file mode 100644 index 0000000..64f6fb9 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_y_180.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionRotateY180 +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 180 Y") + rotation_axis = Vector3(0, 1, 0) + rotation_angle = deg_to_rad(180) diff --git a/addons/cyclops_level_builder/actions/action_rotate_y_90_ccw.gd b/addons/cyclops_level_builder/actions/action_rotate_y_90_ccw.gd new file mode 100644 index 0000000..5d736a4 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_y_90_ccw.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionRotateY90Ccw +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 90 Ccw Y") + rotation_axis = Vector3(0, 1, 0) + rotation_angle = deg_to_rad(90) diff --git a/addons/cyclops_level_builder/actions/action_rotate_y_90_cw.gd b/addons/cyclops_level_builder/actions/action_rotate_y_90_cw.gd new file mode 100644 index 0000000..ea29d28 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_y_90_cw.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionRotateY90Cw +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 90 Cw Y") + rotation_axis = Vector3(0, 1, 0) + rotation_angle = deg_to_rad(-90) diff --git a/addons/cyclops_level_builder/actions/action_rotate_z_180.gd b/addons/cyclops_level_builder/actions/action_rotate_z_180.gd new file mode 100644 index 0000000..9884000 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_z_180.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionRotateZ180 +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 180 Z") + rotation_axis = Vector3(0, 0, 1) + rotation_angle = deg_to_rad(180) diff --git a/addons/cyclops_level_builder/actions/action_rotate_z_90_ccw.gd b/addons/cyclops_level_builder/actions/action_rotate_z_90_ccw.gd new file mode 100644 index 0000000..5e26b48 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_z_90_ccw.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionRotateZ90Ccw +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 90 Ccw Z") + rotation_axis = Vector3(0, 0, 1) + rotation_angle = deg_to_rad(90) diff --git a/addons/cyclops_level_builder/actions/action_rotate_z_90_cw.gd b/addons/cyclops_level_builder/actions/action_rotate_z_90_cw.gd new file mode 100644 index 0000000..f8f4576 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_z_90_cw.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionRotateZ90Cw +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 90 Cw Z") + rotation_axis = Vector3(0, 0, 1) + rotation_angle = deg_to_rad(-90) diff --git a/addons/cyclops_level_builder/actions/action_scale_selection.gd b/addons/cyclops_level_builder/actions/action_scale_selection.gd new file mode 100644 index 0000000..3d78c41 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_scale_selection.gd @@ -0,0 +1,54 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionScaleSelection +extends CyclopsAction + +var scale:Vector3 = Vector3.ONE + +func _init(plugin:CyclopsLevelBuilder, name:String = "", accellerator:Key = KEY_NONE): + super._init(plugin, name, accellerator) + +func _execute(): + var blocks:Array[CyclopsConvexBlock] = plugin.get_selected_blocks() + if blocks.is_empty(): + return + + var pivot:Vector3 = calc_pivot_of_blocks(blocks) + + var cmd:CommandTransformBlocks = CommandTransformBlocks.new() + cmd.builder = plugin + + for block in blocks: + cmd.add_block(block.get_path()) + + var xform:Transform3D = Transform3D.IDENTITY + xform = xform.translated_local(pivot) + xform = xform.scaled_local(scale) + xform = xform.translated_local(-pivot) + cmd.transform = xform + #print("cform %s" % xform) + + var undo:EditorUndoRedoManager = plugin.get_undo_redo() + cmd.add_to_undo_manager(undo) diff --git a/addons/cyclops_level_builder/actions/action_snap_to_grid.gd b/addons/cyclops_level_builder/actions/action_snap_to_grid.gd new file mode 100644 index 0000000..14c2502 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_snap_to_grid.gd @@ -0,0 +1,52 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionSnapToGrid +extends CyclopsAction + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Snap to grid") + + +func _execute(): + var blocks:Array[CyclopsConvexBlock] = plugin.get_selected_blocks() + if blocks.is_empty(): + return + + var pivot:Vector3 = calc_pivot_of_blocks(blocks) + + var cmd:CommandSnapToGrid = CommandSnapToGrid.new() + cmd.builder = plugin + + for block in blocks: + cmd.add_block(block.get_path()) + + + cmd.grid_size = pow(2, plugin.get_global_scene().grid_size) + #print("cform %s" % xform) + + var undo:EditorUndoRedoManager = plugin.get_undo_redo() + cmd.add_to_undo_manager(undo) + + diff --git a/addons/cyclops_level_builder/actions/action_tool_duplicate.gd b/addons/cyclops_level_builder/actions/action_tool_duplicate.gd new file mode 100644 index 0000000..9ec1a52 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_tool_duplicate.gd @@ -0,0 +1,33 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name ActionToolDuplicate +extends CyclopsAction + + +func _init(plugin:CyclopsLevelBuilder, name:String = "", accellerator:Key = KEY_NONE): + super._init(plugin, "Duplicate Selected Blocks") + +func _execute(): + plugin.switch_to_tool(ToolDuplicate.new()) diff --git a/addons/cyclops_level_builder/actions/cyclops_action.gd b/addons/cyclops_level_builder/actions/cyclops_action.gd new file mode 100644 index 0000000..5e4870c --- /dev/null +++ b/addons/cyclops_level_builder/actions/cyclops_action.gd @@ -0,0 +1,54 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CyclopsAction +extends RefCounted + +var plugin:CyclopsLevelBuilder + +var name:String = "" +var accellerator:Key = KEY_NONE + +func _init(plugin:CyclopsLevelBuilder, name:String = "", accellerator:Key = KEY_NONE): + self.plugin = plugin + self.name= name + self.accellerator = accellerator + +func _execute(): + pass + +func calc_pivot_of_blocks(blocks:Array[CyclopsConvexBlock])->Vector3: +# var blocks_root:CyclopsBlocks = plugin.active_node + var grid_step_size:float = pow(2, plugin.get_global_scene().grid_size) + + var bounds:AABB = blocks[0].control_mesh.bounds + for idx in range(1, blocks.size()): + var block:CyclopsConvexBlock = blocks[idx] + bounds = bounds.merge(block.control_mesh.bounds) + + var center:Vector3 = bounds.get_center() + var pivot:Vector3 = MathUtil.snap_to_grid(center, grid_step_size) + + return pivot + diff --git a/addons/cyclops_level_builder/art/cyclops.aseprite b/addons/cyclops_level_builder/art/cyclops.aseprite new file mode 100644 index 0000000..8ed5171 Binary files /dev/null and b/addons/cyclops_level_builder/art/cyclops.aseprite differ diff --git a/addons/cyclops_level_builder/art/cyclops.svg b/addons/cyclops_level_builder/art/cyclops.svg new file mode 100644 index 0000000..a2fc7e1 --- /dev/null +++ b/addons/cyclops_level_builder/art/cyclops.svg @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/cyclops_level_builder/art/cyclops.svg.import b/addons/cyclops_level_builder/art/cyclops.svg.import new file mode 100644 index 0000000..fbb9647 --- /dev/null +++ b/addons/cyclops_level_builder/art/cyclops.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bmbwskudf7ldr" +path="res://.godot/imported/cyclops.svg-62ab1cb5293c5a489284f34e0c642019.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/cyclops.svg" +dest_files=["res://.godot/imported/cyclops.svg-62ab1cb5293c5a489284f34e0c642019.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/cyclops_level_builder/art/cyclops1.png b/addons/cyclops_level_builder/art/cyclops1.png new file mode 100644 index 0000000..aa0202b Binary files /dev/null and b/addons/cyclops_level_builder/art/cyclops1.png differ diff --git a/addons/cyclops_level_builder/art/cyclops1.png.import b/addons/cyclops_level_builder/art/cyclops1.png.import new file mode 100644 index 0000000..881ae35 --- /dev/null +++ b/addons/cyclops_level_builder/art/cyclops1.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://l4qj0lbj3ioa" +path="res://.godot/imported/cyclops1.png-6f459321d21304ca30333893d06ffb09.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/cyclops1.png" +dest_files=["res://.godot/imported/cyclops1.png-6f459321d21304ca30333893d06ffb09.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/cyclops_level_builder/art/cyclops2.png b/addons/cyclops_level_builder/art/cyclops2.png new file mode 100644 index 0000000..bebba72 Binary files /dev/null and b/addons/cyclops_level_builder/art/cyclops2.png differ diff --git a/addons/cyclops_level_builder/art/cyclops2.png.import b/addons/cyclops_level_builder/art/cyclops2.png.import new file mode 100644 index 0000000..8333681 --- /dev/null +++ b/addons/cyclops_level_builder/art/cyclops2.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://oxrgrpeaamq3" +path="res://.godot/imported/cyclops2.png-510e6418526608a41b6474466da5ef6e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/cyclops2.png" +dest_files=["res://.godot/imported/cyclops2.png-510e6418526608a41b6474466da5ef6e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/cyclops_level_builder/art/cyclops_16.aseprite b/addons/cyclops_level_builder/art/cyclops_16.aseprite new file mode 100644 index 0000000..0f07973 Binary files /dev/null and b/addons/cyclops_level_builder/art/cyclops_16.aseprite differ diff --git a/addons/cyclops_level_builder/art/cyclops_16.png b/addons/cyclops_level_builder/art/cyclops_16.png new file mode 100644 index 0000000..835067b Binary files /dev/null and b/addons/cyclops_level_builder/art/cyclops_16.png differ diff --git a/addons/cyclops_level_builder/art/cyclops_16.png.import b/addons/cyclops_level_builder/art/cyclops_16.png.import new file mode 100644 index 0000000..0c2777f --- /dev/null +++ b/addons/cyclops_level_builder/art/cyclops_16.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://df0a5uffpuqg3" +path="res://.godot/imported/cyclops_16.png-f07e4f06ecdf5a5bd3bf65311c5a89e7.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/cyclops_16.png" +dest_files=["res://.godot/imported/cyclops_16.png-f07e4f06ecdf5a5bd3bf65311c5a89e7.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/cyclops_level_builder/art/cyclops_17.png b/addons/cyclops_level_builder/art/cyclops_17.png new file mode 100644 index 0000000..51d5ebc Binary files /dev/null and b/addons/cyclops_level_builder/art/cyclops_17.png differ diff --git a/addons/cyclops_level_builder/art/cyclops_17.png.import b/addons/cyclops_level_builder/art/cyclops_17.png.import new file mode 100644 index 0000000..c60a735 --- /dev/null +++ b/addons/cyclops_level_builder/art/cyclops_17.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ynphxd22kahd" +path="res://.godot/imported/cyclops_17.png-c21222671fab466b90ffb528051b4f8e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/cyclops_17.png" +dest_files=["res://.godot/imported/cyclops_17.png-c21222671fab466b90ffb528051b4f8e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/cyclops_level_builder/art/cyclops_3.aseprite b/addons/cyclops_level_builder/art/cyclops_3.aseprite new file mode 100644 index 0000000..b86a96e Binary files /dev/null and b/addons/cyclops_level_builder/art/cyclops_3.aseprite differ diff --git a/addons/cyclops_level_builder/art/cyclops_3.png b/addons/cyclops_level_builder/art/cyclops_3.png new file mode 100644 index 0000000..eb139e0 Binary files /dev/null and b/addons/cyclops_level_builder/art/cyclops_3.png differ diff --git a/addons/cyclops_level_builder/art/cyclops_3.png.import b/addons/cyclops_level_builder/art/cyclops_3.png.import new file mode 100644 index 0000000..f473f9b --- /dev/null +++ b/addons/cyclops_level_builder/art/cyclops_3.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d0krdms4l6ns4" +path="res://.godot/imported/cyclops_3.png-6415cec0c5295619847f207c8fb5e88e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/cyclops_3.png" +dest_files=["res://.godot/imported/cyclops_3.png-6415cec0c5295619847f207c8fb5e88e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/cyclops_level_builder/art/cyclops_4.png b/addons/cyclops_level_builder/art/cyclops_4.png new file mode 100644 index 0000000..1d4a3ed Binary files /dev/null and b/addons/cyclops_level_builder/art/cyclops_4.png differ diff --git a/addons/cyclops_level_builder/art/cyclops_4.png.import b/addons/cyclops_level_builder/art/cyclops_4.png.import new file mode 100644 index 0000000..1bb0fc1 --- /dev/null +++ b/addons/cyclops_level_builder/art/cyclops_4.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cg3yjatinkymb" +path="res://.godot/imported/cyclops_4.png-e03a17198c56b52428203cf1953feb8c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/cyclops_4.png" +dest_files=["res://.godot/imported/cyclops_4.png-e03a17198c56b52428203cf1953feb8c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/cyclops_level_builder/art/cyclops_closed.png b/addons/cyclops_level_builder/art/cyclops_closed.png new file mode 100644 index 0000000..84ea43f Binary files /dev/null and b/addons/cyclops_level_builder/art/cyclops_closed.png differ diff --git a/addons/cyclops_level_builder/art/cyclops_closed.png.import b/addons/cyclops_level_builder/art/cyclops_closed.png.import new file mode 100644 index 0000000..d4091e1 --- /dev/null +++ b/addons/cyclops_level_builder/art/cyclops_closed.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dd8xjcq5k2kia" +path="res://.godot/imported/cyclops_closed.png-8f54cf7552f8e17ac6aa0c8d6378241b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/cyclops_closed.png" +dest_files=["res://.godot/imported/cyclops_closed.png-8f54cf7552f8e17ac6aa0c8d6378241b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/cyclops_level_builder/art/cyclops_open.png b/addons/cyclops_level_builder/art/cyclops_open.png new file mode 100644 index 0000000..e80d75b Binary files /dev/null and b/addons/cyclops_level_builder/art/cyclops_open.png differ diff --git a/addons/cyclops_level_builder/art/cyclops_open.png.import b/addons/cyclops_level_builder/art/cyclops_open.png.import new file mode 100644 index 0000000..a71ecaa --- /dev/null +++ b/addons/cyclops_level_builder/art/cyclops_open.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dv78ucvwmycdh" +path="res://.godot/imported/cyclops_open.png-44d55f3db65056f90cc00f3559bf1cb3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/cyclops_open.png" +dest_files=["res://.godot/imported/cyclops_open.png-44d55f3db65056f90cc00f3559bf1cb3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/cyclops_level_builder/art/materialTest.blend b/addons/cyclops_level_builder/art/materialTest.blend new file mode 100644 index 0000000..40ac1bb Binary files /dev/null and b/addons/cyclops_level_builder/art/materialTest.blend differ diff --git a/addons/cyclops_level_builder/art/materialTest.blend.import b/addons/cyclops_level_builder/art/materialTest.blend.import new file mode 100644 index 0000000..772bff9 --- /dev/null +++ b/addons/cyclops_level_builder/art/materialTest.blend.import @@ -0,0 +1,48 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://bp8tbh8g23hkk" +path="res://.godot/imported/materialTest.blend-aa817559d244ec647e2795b1bec725af.scn" + +[deps] + +source_file="res://addons/cyclops_level_builder/art/materialTest.blend" +dest_files=["res://.godot/imported/materialTest.blend-aa817559d244ec647e2795b1bec725af.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={} +gltf/embedded_image_handling=1 +blender/nodes/visible=0 +blender/nodes/punctual_lights=true +blender/nodes/cameras=true +blender/nodes/custom_properties=true +blender/nodes/modifiers=1 +blender/meshes/colors=false +blender/meshes/uvs=true +blender/meshes/normals=true +blender/meshes/tangents=true +blender/meshes/skins=2 +blender/meshes/export_bones_deforming_mesh_only=false +blender/materials/unpack_enabled=true +blender/materials/export_materials=1 +blender/animation/limit_playback=true +blender/animation/always_sample=true +blender/animation/group_tracks=true diff --git a/addons/cyclops_level_builder/art/materialTest.blend1 b/addons/cyclops_level_builder/art/materialTest.blend1 new file mode 100644 index 0000000..53335d8 Binary files /dev/null and b/addons/cyclops_level_builder/art/materialTest.blend1 differ diff --git a/addons/cyclops_level_builder/art/materialTest.glb b/addons/cyclops_level_builder/art/materialTest.glb new file mode 100644 index 0000000..8f993f0 Binary files /dev/null and b/addons/cyclops_level_builder/art/materialTest.glb differ diff --git a/addons/cyclops_level_builder/art/materialTest.glb.import b/addons/cyclops_level_builder/art/materialTest.glb.import new file mode 100644 index 0000000..23a3c5c --- /dev/null +++ b/addons/cyclops_level_builder/art/materialTest.glb.import @@ -0,0 +1,32 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://dxpve684yme21" +path="res://.godot/imported/materialTest.glb-89a5487d9d67cb795bea9d0f40563ce7.scn" + +[deps] + +source_file="res://addons/cyclops_level_builder/art/materialTest.glb" +dest_files=["res://.godot/imported/materialTest.glb-89a5487d9d67cb795bea9d0f40563ce7.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={} +gltf/embedded_image_handling=1 diff --git a/addons/cyclops_level_builder/art/textures/checkerboard.aseprite b/addons/cyclops_level_builder/art/textures/checkerboard.aseprite new file mode 100644 index 0000000..296e04f Binary files /dev/null and b/addons/cyclops_level_builder/art/textures/checkerboard.aseprite differ diff --git a/addons/cyclops_level_builder/art/textures/checkerboard.png b/addons/cyclops_level_builder/art/textures/checkerboard.png new file mode 100644 index 0000000..393ca46 Binary files /dev/null and b/addons/cyclops_level_builder/art/textures/checkerboard.png differ diff --git a/addons/cyclops_level_builder/art/textures/checkerboard.png.import b/addons/cyclops_level_builder/art/textures/checkerboard.png.import new file mode 100644 index 0000000..f12ecf8 --- /dev/null +++ b/addons/cyclops_level_builder/art/textures/checkerboard.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b78mg60xhic6n" +path.s3tc="res://.godot/imported/checkerboard.png-cfbf91dbc6f1912b9574735ecca5a514.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/textures/checkerboard.png" +dest_files=["res://.godot/imported/checkerboard.png-cfbf91dbc6f1912b9574735ecca5a514.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/addons/cyclops_level_builder/art/textures/grid_cell.aseprite b/addons/cyclops_level_builder/art/textures/grid_cell.aseprite new file mode 100644 index 0000000..172a35e Binary files /dev/null and b/addons/cyclops_level_builder/art/textures/grid_cell.aseprite differ diff --git a/addons/cyclops_level_builder/art/textures/grid_cell.png b/addons/cyclops_level_builder/art/textures/grid_cell.png new file mode 100644 index 0000000..6e5364b Binary files /dev/null and b/addons/cyclops_level_builder/art/textures/grid_cell.png differ diff --git a/addons/cyclops_level_builder/art/textures/grid_cell.png.import b/addons/cyclops_level_builder/art/textures/grid_cell.png.import new file mode 100644 index 0000000..56f87d2 --- /dev/null +++ b/addons/cyclops_level_builder/art/textures/grid_cell.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dpoaquoridpp6" +path.bptc="res://.godot/imported/grid_cell.png-608181fcff7b2e489ee715ed212734c5.bptc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/textures/grid_cell.png" +dest_files=["res://.godot/imported/grid_cell.png-608181fcff7b2e489ee715ed212734c5.bptc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=true +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/addons/cyclops_level_builder/art/textures/grid_cell2.aseprite b/addons/cyclops_level_builder/art/textures/grid_cell2.aseprite new file mode 100644 index 0000000..41b75c9 Binary files /dev/null and b/addons/cyclops_level_builder/art/textures/grid_cell2.aseprite differ diff --git a/addons/cyclops_level_builder/art/textures/grid_cell2.png b/addons/cyclops_level_builder/art/textures/grid_cell2.png new file mode 100644 index 0000000..67a33e3 Binary files /dev/null and b/addons/cyclops_level_builder/art/textures/grid_cell2.png differ diff --git a/addons/cyclops_level_builder/art/textures/grid_cell2.png.import b/addons/cyclops_level_builder/art/textures/grid_cell2.png.import new file mode 100644 index 0000000..37bfc32 --- /dev/null +++ b/addons/cyclops_level_builder/art/textures/grid_cell2.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bnlqi20ay4vs1" +path="res://.godot/imported/grid_cell2.png-1f268fac69e50a444ba304e9119a8d5b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/textures/grid_cell2.png" +dest_files=["res://.godot/imported/grid_cell2.png-1f268fac69e50a444ba304e9119a8d5b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/addons/cyclops_level_builder/commands/cmd_add_block.gd b/addons/cyclops_level_builder/commands/cmd_add_block.gd new file mode 100644 index 0000000..62001a6 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_add_block.gd @@ -0,0 +1,69 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandAddBlock2 +extends CyclopsCommand + +#Public data to set before activating command +var blocks_root_path:NodePath +var block_name:String +var bounds:AABB +var material_path:String +var uv_transform:Transform2D = Transform2D.IDENTITY + +#Private data +var block_path:NodePath + +func _init(): + command_name = "Add block" + +func do_it(): + var block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + + var blocks_root:CyclopsBlocks = builder.get_node(blocks_root_path) + blocks_root.add_child(block) + block.owner = builder.get_editor_interface().get_edited_scene_root() + block.name = block_name + + var material_id:int = -1 + if ResourceLoader.exists(material_path): + var mat = load(material_path) + if mat is Material: + material_id = 0 + block.materials.append(mat) + + + var mesh:ConvexVolume = ConvexVolume.new() + mesh.init_block(bounds, uv_transform, material_id) + + block.block_data = mesh.to_convex_block_data() + block_path = block.get_path() + +# print("AddBlockCommand do_it() %s %s" % [block_inst_id, bounds]) + +func undo_it(): + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.queue_free() + +# print("AddBlockCommand undo_it()") diff --git a/addons/cyclops_level_builder/commands/cmd_add_cylinder.gd b/addons/cyclops_level_builder/commands/cmd_add_cylinder.gd new file mode 100644 index 0000000..c8bc3a8 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_add_cylinder.gd @@ -0,0 +1,102 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandAddCylinder +extends CyclopsCommand + +#Public data to set before activating command +var blocks_root_path:NodePath +#var block_name:String +var block_name_prefix:String = "Block_" +var origin:Vector3 +var axis_normal:Vector3 +var height:float +var radius_inner:float +var radius_outer:float +var segments:int +var tube:bool = false + +var material_path:String +var uv_transform:Transform2D = Transform2D.IDENTITY + +#Private data +var block_paths:Array[NodePath] + +func _init(): + command_name = "Add cylinder" + +func create_block(blocks_root:CyclopsBlocks, mat:Material)->CyclopsConvexBlock: + var block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + blocks_root.add_child(block) + block.owner = builder.get_editor_interface().get_edited_scene_root() + block.name = GeneralUtil.find_unique_name(builder.active_node, block_name_prefix) + + if mat: + block.materials.append(mat) + + return block + + +func do_it(): + var blocks_root:CyclopsBlocks = builder.get_node(blocks_root_path) + + var material:Material + var material_id:int = -1 + if ResourceLoader.exists(material_path): + var mat = load(material_path) + if mat is Material: + material_id = 0 + material = mat + + if tube: + var bounding_points_inner:PackedVector3Array = MathUtil.create_circle_points(origin, axis_normal, radius_inner, segments) + var bounding_points_outer:PackedVector3Array = MathUtil.create_circle_points(origin, axis_normal, radius_outer, segments) + + for p_idx0 in bounding_points_inner.size(): + var p_idx1:int = wrap(p_idx0 + 1, 0, bounding_points_inner.size()) + + var block:CyclopsConvexBlock = create_block(blocks_root, material) + + var mesh:ConvexVolume = ConvexVolume.new() + var base_points:PackedVector3Array = [bounding_points_inner[p_idx0], bounding_points_inner[p_idx1], bounding_points_outer[p_idx1], bounding_points_outer[p_idx0]] + + mesh.init_prism(base_points, axis_normal * height, uv_transform, material_id) + + block.block_data = mesh.to_convex_block_data() + block_paths.append(block.get_path()) + + else: + var block:CyclopsConvexBlock = create_block(blocks_root, material) + + var bounding_points:PackedVector3Array = MathUtil.create_circle_points(origin, axis_normal, radius_outer, segments) + var mesh:ConvexVolume = ConvexVolume.new() + mesh.init_prism(bounding_points, axis_normal * height, uv_transform, material_id) + + block.block_data = mesh.to_convex_block_data() + block_paths.append(block.get_path()) + +func undo_it(): + for path in block_paths: + var block:CyclopsConvexBlock = builder.get_node(path) + block.queue_free() diff --git a/addons/cyclops_level_builder/commands/cmd_add_prism.gd b/addons/cyclops_level_builder/commands/cmd_add_prism.gd new file mode 100644 index 0000000..da09275 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_add_prism.gd @@ -0,0 +1,69 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandAddPrism +extends CyclopsCommand + +var blocks_root_path:NodePath +var block_name:String +var base_polygon:PackedVector3Array +var extrude:Vector3 +var uv_transform:Transform2D +var material_path:String + +#Private +var block_path:NodePath + +func _init(): + command_name = "Add prism" + +func do_it(): + var block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + + var blocks_root:CyclopsBlocks = builder.get_node(blocks_root_path) + blocks_root.add_child(block) + block.owner = builder.get_editor_interface().get_edited_scene_root() +# block.owner = block_owner + block.name = block_name + + var material_id:int = -1 + if ResourceLoader.exists(material_path): + var mat = load(material_path) + if mat is Material: + material_id = 0 + block.materials.append(mat) + + var mesh:ConvexVolume = ConvexVolume.new() + mesh.init_prism(base_polygon, extrude, uv_transform, material_id) + + block.block_data = mesh.to_convex_block_data() + block_path = block.get_path() + +# print("AddBlockCommand do_it() %s %s" % [block_inst_id, bounds]) + +func undo_it(): + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.queue_free() + +# print("AddBlockCommand undo_it()") diff --git a/addons/cyclops_level_builder/commands/cmd_add_stairs.gd b/addons/cyclops_level_builder/commands/cmd_add_stairs.gd new file mode 100644 index 0000000..5ab6fd1 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_add_stairs.gd @@ -0,0 +1,150 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandAddStairs +extends CyclopsCommand + +#var blocks_root_inst_id:int +var blocks_root_path:NodePath +var block_name_prefix:String +var floor_normal:Vector3 +var drag_origin:Vector3 +var base_drag_cur:Vector3 +var block_drag_cur:Vector3 +var step_height:float = .25 +var step_depth:float = .5 +var direction:int = 0 + +var uv_transform:Transform2D +var material_path:String + +#Private data +var block_paths:Array[NodePath] + +func _init(): + command_name = "Add stairs" + +func create_block(blocks_root:CyclopsBlocks, mat:Material)->CyclopsConvexBlock: + var block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + blocks_root.add_child(block) + block.owner = builder.get_editor_interface().get_edited_scene_root() + block.name = GeneralUtil.find_unique_name(builder.active_node, block_name_prefix) + + if mat: + block.materials.append(mat) + + return block + + +func do_it(): + var blocks_root:CyclopsBlocks = builder.get_node(blocks_root_path) + + var material:Material + var material_id:int = -1 + if ResourceLoader.exists(material_path): + var mat = load(material_path) + if mat is Material: + material_id = 0 + material = mat + + var tan_bi:Array[Vector3] = MathUtil.get_axis_aligned_tangent_and_binormal(floor_normal) + var u_normal:Vector3 = tan_bi[0] + var v_normal:Vector3 = tan_bi[1] + + #Rotate ccw by 90 degree increments + match direction: + 1: + var tmp:Vector3 = u_normal + u_normal = -v_normal + v_normal = tmp + 2: + u_normal = -u_normal + v_normal = -v_normal + 3: + var tmp:Vector3 = -u_normal + u_normal = v_normal + v_normal = tmp + + var u_span:Vector3 = (base_drag_cur - drag_origin).project(u_normal) + var v_span:Vector3 = (base_drag_cur - drag_origin).project(v_normal) + + var stairs_origin:Vector3 = drag_origin + if u_span.dot(u_normal) < 0: + stairs_origin += u_span + u_span = -u_span + if v_span.dot(v_normal) < 0: + stairs_origin += v_span + v_span = -v_span + + #Stairs should ascend along v axis + var height_offset = block_drag_cur - base_drag_cur + if height_offset.dot(floor_normal) < 0: + return + var num_steps:int = min(v_span.length() / step_depth, height_offset.length() / step_height) + + var max_height:float = floor(height_offset.length() / step_height) * step_height + + var step_span:Vector3 = v_normal * step_depth + for i in num_steps: + var base_points:PackedVector3Array = [stairs_origin + step_span * i, \ + stairs_origin + u_span + step_span * i, \ + stairs_origin + u_span + step_span * (i + 1), \ + stairs_origin + step_span * (i + 1)] + + var mesh:ConvexVolume = ConvexVolume.new() + mesh.init_prism(base_points, \ + floor_normal * (max_height - step_height * i), \ + uv_transform, material_id) + + var block:CyclopsConvexBlock = create_block(blocks_root, material) + + block.block_data = mesh.to_convex_block_data() + block_paths.append(block.get_path()) + +# global_scene.draw_prism(base_points, \ +# floor_normal * (max_height - step_height * i), \ +# global_scene.tool_material) + + +# var bounding_points_inner:PackedVector3Array = MathUtil.create_circle_points(origin, axis_normal, radius_inner, segments) +# var bounding_points_outer:PackedVector3Array = MathUtil.create_circle_points(origin, axis_normal, radius_outer, segments) +# +# for p_idx0 in bounding_points_inner.size(): +# var p_idx1:int = wrap(p_idx0 + 1, 0, bounding_points_inner.size()) +# +# var block:CyclopsConvexBlock = create_block(blocks_root, material) +# +# var mesh:ConvexVolume = ConvexVolume.new() +# var base_points:PackedVector3Array = [bounding_points_inner[p_idx0], bounding_points_inner[p_idx1], bounding_points_outer[p_idx1], bounding_points_outer[p_idx0]] +# +# mesh.init_prism(base_points, axis_normal * height, uv_transform, material_id) +# +# block.block_data = mesh.to_convex_block_data() +# block_paths.append(block.get_path()) + + +func undo_it(): + for path in block_paths: + var block:CyclopsConvexBlock = builder.get_node(path) + block.queue_free() diff --git a/addons/cyclops_level_builder/commands/cmd_add_vertices.gd b/addons/cyclops_level_builder/commands/cmd_add_vertices.gd new file mode 100644 index 0000000..828d879 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_add_vertices.gd @@ -0,0 +1,73 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandAddVertices +extends CyclopsCommand + + +#Public +var points_to_add:PackedVector3Array +var block_path:NodePath + +#Private +var tracked_block_data:ConvexBlockData +var selected_points:PackedVector3Array + + +func _init(): + command_name = "Add vertices" + +func do_it(): + var block:CyclopsConvexBlock = builder.get_node(block_path) + + if !tracked_block_data: + var tracked_vol:ConvexVolume = block.control_mesh + tracked_block_data = tracked_vol.to_convex_block_data() + + for v in tracked_vol.vertices: + if v.selected: + selected_points.append(v.point) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(tracked_block_data) + + var point_list:PackedVector3Array = vol.get_points() + point_list.append_array(points_to_add) + + var new_vol:ConvexVolume = ConvexVolume.new() + new_vol.init_from_points(point_list) + new_vol.copy_face_attributes(vol) + + + for v_idx in new_vol.vertices.size(): + var v:ConvexVolume.VertexInfo = new_vol.vertices[v_idx] + if selected_points.has(v.point): + v.selected = true + + block.block_data = new_vol.to_convex_block_data() + + +func undo_it(): + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = tracked_block_data diff --git a/addons/cyclops_level_builder/commands/cmd_clip_block.gd b/addons/cyclops_level_builder/commands/cmd_clip_block.gd new file mode 100644 index 0000000..e27246b --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_clip_block.gd @@ -0,0 +1,102 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandClipBlock +extends CyclopsCommand + +#Public data to set before activating command +var blocks_root_path:NodePath +var block_path:NodePath +var cut_plane:Plane +var uv_transform:Transform2D = Transform2D.IDENTITY +var material_path:String = "" + +#Private +var block_sibling_name:String +var old_block_data:ConvexBlockData +var old_mat_list:Array[Material] +var block_sibling_path:NodePath + +func _init(): + command_name = "Clip block" + +func get_material_index(mat_list:Array[Material], path:String)->int: + if path.is_empty(): + return -1 + for i in mat_list.size(): + var mat:Material = mat_list[i] + if mat != null && mat.resource_path == path: + return i + return -1 + +func do_it(): + var blocks_root:CyclopsBlocks = builder.get_node(blocks_root_path) + var block:CyclopsConvexBlock = builder.get_node(block_path) + + old_block_data = block.block_data.duplicate() + old_mat_list = block.materials.duplicate() + + var new_mat_list0:Array[Material] = old_mat_list.duplicate() + + var cut_mat_idx = get_material_index(old_mat_list, material_path) + if cut_mat_idx == -1: + var mat = load(material_path) + if mat is Material: + cut_mat_idx = new_mat_list0.size() + new_mat_list0.append(mat) + + + var new_mat_list1:Array[Material] = new_mat_list0.duplicate() + + var cut_plane_reverse:Plane = Plane(-cut_plane.normal, cut_plane.get_center()) + + var vol0:ConvexVolume = block.control_mesh.cut_with_plane(cut_plane, uv_transform, cut_mat_idx) + var vol1:ConvexVolume = block.control_mesh.cut_with_plane(MathUtil.flip_plane(cut_plane), uv_transform, cut_mat_idx) + + #Set data of existing block + block.block_data = vol0.to_convex_block_data() + block.materials = new_mat_list0 + + #Create second block + var block_sibling:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + + blocks_root.add_child(block_sibling) + block_sibling.owner = builder.get_editor_interface().get_edited_scene_root() + block_sibling.name = block_sibling_name + block_sibling.selected = block.selected + block_sibling_path = block_sibling.get_path() + + block_sibling.block_data = vol1.to_convex_block_data() + block_sibling.materials = new_mat_list1 + + +func undo_it(): + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = old_block_data + block.materials = old_mat_list.duplicate() + + var block_sibling:CyclopsConvexBlock = builder.get_node(block_sibling_path) + block_sibling.queue_free() + + diff --git a/addons/cyclops_level_builder/commands/cmd_delete_blocks.gd b/addons/cyclops_level_builder/commands/cmd_delete_blocks.gd new file mode 100644 index 0000000..084350d --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_delete_blocks.gd @@ -0,0 +1,93 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandDeleteBlocks +extends CyclopsCommand + +class TrackedBlock extends RefCounted: + var path:NodePath + var path_parent:NodePath + var data:ConvexBlockData + var materials:Array[Material] + var selected:bool + var name:String + + func _init(block:CyclopsConvexBlock): + path = block.get_path() + path_parent = block.get_parent().get_path() + name = block.name + data = block.block_data.duplicate() + selected = block.selected + materials = block.materials + +#Public +var block_paths:Array[NodePath] + +#Private +var tracked_blocks:Array[TrackedBlock] + +func _init(): + command_name = "Delete blocks" + +func will_change_anything(): + if !block_paths.is_empty(): + return true + + return false + + +func do_it(): + #print("Delete do_it") + + if tracked_blocks.is_empty(): + var points:PackedVector3Array + + for path in block_paths: + var block:CyclopsConvexBlock = builder.get_node(path) + var tracker:TrackedBlock = TrackedBlock.new(block) + tracked_blocks.append(tracker) + + #Delete source blocks + for block_path in block_paths: + var del_block:CyclopsConvexBlock = builder.get_node(block_path) + del_block.queue_free() + + +func undo_it(): + #print("Delete undo_it") + for tracked in tracked_blocks: + var parent = builder.get_node(tracked.path_parent) + + var block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + block.block_data = tracked.data + block.materials = tracked.materials + block.name = tracked.name + block.selected = tracked.selected + + parent.add_child(block) + block.owner = builder.get_editor_interface().get_edited_scene_root() + + + + diff --git a/addons/cyclops_level_builder/commands/cmd_duplicate_blocks.gd b/addons/cyclops_level_builder/commands/cmd_duplicate_blocks.gd new file mode 100644 index 0000000..5158b77 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_duplicate_blocks.gd @@ -0,0 +1,87 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandDuplicateBlocks +extends CyclopsCommand + +#Public +var blocks_root_path:NodePath +var blocks_to_duplicate:Array[NodePath] +var move_offset:Vector3 +var lock_uvs:bool + +#Private +class BlockInfo extends RefCounted: + var new_block:CyclopsConvexBlock + var source_data:ConvexBlockData + #var materials:Array[Material] + + func _init(new_block:CyclopsConvexBlock, source_data:ConvexBlockData): + self.new_block = new_block + self.source_data = source_data + +var added_blocks:Array[BlockInfo] + +func will_change_anything(): + return !added_blocks.is_empty() + +func do_it(): + if added_blocks.is_empty(): + #Create new blocks + for block_path in blocks_to_duplicate: + var new_block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + + var source_block:CyclopsConvexBlock = builder.get_node(block_path) + + var blocks_root:CyclopsBlocks = builder.get_node(blocks_root_path) + new_block.name = GeneralUtil.find_unique_name(blocks_root, source_block.name) + blocks_root.add_child(new_block) + new_block.owner = builder.get_editor_interface().get_edited_scene_root() + + var info:BlockInfo = BlockInfo.new(new_block, source_block.block_data) + new_block.materials = source_block.materials + new_block.selected = true + + added_blocks.append(info) + + for path in blocks_to_duplicate: + var block:CyclopsConvexBlock = builder.get_node(path) + block.selected = false + + for info in added_blocks: + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(info.source_data) + vol.translate(move_offset, lock_uvs) + info.new_block.block_data = vol.to_convex_block_data() + + +func undo_it(): + for block in added_blocks: + block.new_block.queue_free() + added_blocks = [] + + for path in blocks_to_duplicate: + var block:CyclopsConvexBlock = builder.get_node(path) + block.selected = true + diff --git a/addons/cyclops_level_builder/commands/cmd_merge_blocks.gd b/addons/cyclops_level_builder/commands/cmd_merge_blocks.gd new file mode 100644 index 0000000..8c75922 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_merge_blocks.gd @@ -0,0 +1,149 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandMergeBlocks +extends CyclopsCommand + +class TrackedBlock extends RefCounted: + var path:NodePath + var path_parent:NodePath + var data:ConvexBlockData + var materials:Array[Material] + var selected:bool + var name:String + + func _init(block:CyclopsConvexBlock): + path = block.get_path() + path_parent = block.get_parent().get_path() + name = block.name + data = block.block_data.duplicate() + selected = block.selected + materials = block.materials + +#Public +var block_paths:Array[NodePath] +var block_name_prefix:String = "Block_" + +#Private +var tracked_blocks:Array[TrackedBlock] +var merged_block_data:ConvexBlockData +var merged_mat_list:Array[Material] +var merged_block_path:NodePath + +func _init(): + command_name = "Merge blocks" + +func get_best_face(centroid:Vector3, ref_list:Array[NodePath])->Array: + var best_face:ConvexVolume.FaceInfo + var best_dist:float = INF + var best_block:CyclopsConvexBlock + + for block_path in ref_list: + var block:CyclopsConvexBlock = builder.get_node(block_path) + var vol:ConvexVolume = block.control_mesh + for f in vol.faces: + var face_center:Vector3 = f.get_centroid() + var offset:float = centroid.distance_squared_to(face_center) + if offset < best_dist: + best_dist = offset + best_face = f + best_block = block + + if best_face.material_id == -1: + return [best_face, null] + return [best_face, best_block.materials[best_face.material_id]] + +func copy_face_attributes(target:ConvexVolume, ref_list:Array[NodePath])->Array[Material]: + var mat_list:Array[Material] + + for f in target.faces: + var centroid:Vector3 = f.get_centroid() + var res:Array = get_best_face(centroid, ref_list) + var ref_face:ConvexVolume.FaceInfo = res[0] + var material:Material = res[1] + + var mat_idx:int = -1 + if material != null: + mat_idx = mat_list.find(material) + if mat_idx == -1: + mat_idx = mat_list.size() + mat_list.append(material) + + f.material_id = mat_idx + f.uv_transform = ref_face.uv_transform + f.selected = ref_face.selected + + return mat_list + +func do_it(): + if tracked_blocks.is_empty(): + var points:PackedVector3Array + + for path in block_paths: + var block:CyclopsConvexBlock = builder.get_node(path) + var tracker:TrackedBlock = TrackedBlock.new(block) + tracked_blocks.append(tracker) + + points.append_array(block.control_mesh.get_points()) + + var merged_vol:ConvexVolume = ConvexVolume.new() + merged_vol.init_from_points(points) + merged_mat_list = copy_face_attributes(merged_vol, block_paths) + merged_block_data = merged_vol.to_convex_block_data() + + + #Delete source blocks + for block_path in block_paths: + var del_block:CyclopsConvexBlock = builder.get_node(block_path) + del_block.queue_free() + + #Create block + var block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + var parent:Node = builder.get_node(tracked_blocks[0].path_parent) + parent.add_child(block) + block.owner = builder.get_editor_interface().get_edited_scene_root() + block.name = GeneralUtil.find_unique_name(parent, block_name_prefix) + block.block_data = merged_block_data + block.materials = merged_mat_list + #block.materials + + merged_block_path = block.get_path() + +func undo_it(): +# var blocks_root:CyclopsBlocks = builder.get_node(blocks_root_path) + var merged_block:CyclopsConvexBlock = builder.get_node(merged_block_path) + merged_block.queue_free() + +# for i in blocks_to_merge.size(): + for tracked in tracked_blocks: + var parent = builder.get_node(tracked.path_parent) + + var block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + block.block_data = tracked.data + block.materials = tracked.materials + block.name = tracked.name + block.selected = tracked.selected + + parent.add_child(block) + block.owner = builder.get_editor_interface().get_edited_scene_root() diff --git a/addons/cyclops_level_builder/commands/cmd_move_blocks.gd b/addons/cyclops_level_builder/commands/cmd_move_blocks.gd new file mode 100644 index 0000000..2081e16 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_move_blocks.gd @@ -0,0 +1,64 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandMoveBlocks +extends CyclopsCommand + +#Public data to set before activating command +var move_offset:Vector3 +var lock_uvs:bool = false + +#Private +var blocks_to_move:Array[NodePath] +var tracked_block_data:Array[ConvexBlockData] + +func _init(): + command_name = "Move blocks" + +#Add blocks to be moved here +func add_block(block_path:NodePath): + blocks_to_move.append(block_path) + + var block:CyclopsConvexBlock = builder.get_node(block_path) + #tracked_blocks.append(block) + tracked_block_data.append(block.block_data.duplicate()) + +#Moves all blocks from the start position by this amount +func move_to(offset:Vector3): + for i in blocks_to_move.size(): + var block:CyclopsConvexBlock = builder.get_node(blocks_to_move[i]) + + var ctl_mesh:ConvexVolume = ConvexVolume.new() + ctl_mesh.init_from_convex_block_data(tracked_block_data[i]) + ctl_mesh.translate(offset, lock_uvs) + var result_data:ConvexBlockData = ctl_mesh.to_convex_block_data() + block.block_data = result_data + #tracked_blocks[block_idx].block_data = result_data + +func do_it(): + move_to(move_offset) + +func undo_it(): + move_to(Vector3.ZERO) + diff --git a/addons/cyclops_level_builder/commands/cmd_move_edges.gd b/addons/cyclops_level_builder/commands/cmd_move_edges.gd new file mode 100644 index 0000000..1ff8bd2 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_move_edges.gd @@ -0,0 +1,132 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandMoveEdges +extends CyclopsCommand + + +class BlockEdgeChanges extends RefCounted: + var block_path:NodePath + var edge_indices:Array[int] = [] + var tracked_block_data:ConvexBlockData + +#Public +var move_offset:Vector3 = Vector3.ZERO + +#Private +var block_map:Dictionary = {} + +func add_edge(block_path:NodePath, index:int): + add_edges(block_path, [index]) + +func add_edges(block_path:NodePath, indices:Array[int]): + var changes:BlockEdgeChanges + if block_map.has(block_path): + changes = block_map[block_path] + else: + changes = BlockEdgeChanges.new() + changes.block_path = block_path + var block:CyclopsConvexBlock = builder.get_node(block_path) + changes.tracked_block_data = block.block_data + block_map[block_path] = changes + + for index in indices: + if !changes.edge_indices.has(index): + changes.edge_indices.append(index) + +func _init(): + command_name = "Move edges" + + +func do_it(): +# print("cmd move edges- DO IT") + + for block_path in block_map.keys(): + +# print("%s" % block_path) + + var block:CyclopsConvexBlock = builder.get_node(block_path) + var rec:BlockEdgeChanges = block_map[block_path] + +# print("rec %s" % rec) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + +# print("init done") + + #var moved_vert_indices:PackedInt32Array + var new_points:PackedVector3Array + var new_sel_centroids:PackedVector3Array + var moved_indices:Array[int] = [] + for edge_index in rec.edge_indices: + var e:ConvexVolume.EdgeInfo = vol.edges[edge_index] + var v0:ConvexVolume.VertexInfo = vol.vertices[e.start_index] + var v1:ConvexVolume.VertexInfo = vol.vertices[e.end_index] + if e.selected: + new_sel_centroids.append((v0.point + v1.point) / 2 + move_offset) + + if !moved_indices.has(e.start_index): + new_points.append(v0.point + move_offset) + moved_indices.append(e.start_index) + if !moved_indices.has(e.end_index): + new_points.append(v1.point + move_offset) + moved_indices.append(e.end_index) + else: + if !moved_indices.has(e.start_index): + new_points.append(v0.point + move_offset) + moved_indices.append(e.start_index) + if !moved_indices.has(e.end_index): + new_points.append(v1.point + move_offset) + moved_indices.append(e.end_index) + + for v_idx in vol.vertices.size(): + if !moved_indices.has(v_idx): + new_points.append(vol.vertices[v_idx].point) + #print("new points_ %s" % new_points) + + var new_vol:ConvexVolume = ConvexVolume.new() + new_vol.init_from_points(new_points) + + new_vol.copy_face_attributes(vol) + + #print("new init done") + + #Copy selection data + for e_idx in new_vol.edges.size(): + var e_new:ConvexVolume.EdgeInfo = new_vol.edges[e_idx] + var centroid:Vector3 = (new_vol.vertices[e_new.start_index].point + new_vol.vertices[e_new.end_index].point) / 2 +# print ("vol point %s " % v1.point) + if new_sel_centroids.has(centroid): +# print("set sel") + e_new.selected = true + + block.block_data = new_vol.to_convex_block_data() + + +func undo_it(): + for block_path in block_map.keys(): + var rec:BlockEdgeChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = rec.tracked_block_data diff --git a/addons/cyclops_level_builder/commands/cmd_move_face_planar.gd b/addons/cyclops_level_builder/commands/cmd_move_face_planar.gd new file mode 100644 index 0000000..8cff421 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_move_face_planar.gd @@ -0,0 +1,104 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandMoveFacePlanar +extends CyclopsCommand + +#Public data to set before activating command +var blocks_root_path:NodePath +var block_path:NodePath +var move_dir_normal:Vector3 +var move_amount:float +var face_id:int +var lock_uvs:bool = false + + +#Private +var block_name:String +var block_selected:bool +var tracked_block_data:ConvexBlockData + +var deleted:bool = false + + +func _init(): + command_name = "Move face planar" + +func move_to(offset:Vector3, intermediate:bool): +# print("move_to off %s faceid %s amount %s movedir %s" % [offset, face_id, move_amount, move_dir_normal]) + if !tracked_block_data: + var block:CyclopsConvexBlock = builder.get_node(block_path) + + block_name = block.name + block_selected = block.selected + tracked_block_data = block.block_data + + var ctl_mesh:ConvexVolume = ConvexVolume.new() + ctl_mesh.init_from_convex_block_data(tracked_block_data) + var new_mesh:ConvexVolume = ctl_mesh.translate_face_plane(face_id, offset, lock_uvs) + + #print("offset %s" % offset) + #print("ctl_mesh %s" % ctl_mesh.get_points()) + + + var block:CyclopsConvexBlock = builder.get_node(block_path) + + if new_mesh == null || new_mesh.is_empty(): + #print("new_mesh EMPTY") + block.block_data = null + if !intermediate: + block.queue_free() + deleted = true + return + + #ctl_mesh.remove_unused_planes() + #print("new_mesh %s" % new_mesh.get_points()) + + var result_data:ConvexBlockData = new_mesh.to_convex_block_data() +# var result_data:ConvexBlockData = ctl_mesh.to_convex_block_data() + block.block_data = result_data + + +func do_it_intermediate(): + move_to(move_dir_normal * move_amount, true) + +func do_it(): + move_to(move_dir_normal * move_amount, false) + +func undo_it(): + if deleted: + var block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + + var blocks_root:CyclopsBlocks = builder.get_node(blocks_root_path) + blocks_root.add_child(block) + block.owner = builder.get_editor_interface().get_edited_scene_root() + block.block_data = tracked_block_data + block.name = block_name + block.selected = block_selected + + deleted = false + return + + move_to(Vector3.ZERO, false) + diff --git a/addons/cyclops_level_builder/commands/cmd_move_faces.gd b/addons/cyclops_level_builder/commands/cmd_move_faces.gd new file mode 100644 index 0000000..8465319 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_move_faces.gd @@ -0,0 +1,131 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandMoveFaces +extends CyclopsCommand + +class BlockFaceChanges extends RefCounted: + var block_path:NodePath + var face_indices:Array[int] = [] + var tracked_block_data:ConvexBlockData + +#Public +var move_offset:Vector3 = Vector3.ZERO + +#Private +var block_map:Dictionary = {} + + +func add_face(block_path:NodePath, index:int): +# print("Adding face %s %s" % [block_path, index]) + add_faces(block_path, [index]) + +func add_faces(block_path:NodePath, indices:Array[int]): + var changes:BlockFaceChanges + if block_map.has(block_path): + changes = block_map[block_path] + else: + changes = BlockFaceChanges.new() + changes.block_path = block_path + var block:CyclopsConvexBlock = builder.get_node(block_path) + changes.tracked_block_data = block.block_data + block_map[block_path] = changes + + for index in indices: + if !changes.face_indices.has(index): + changes.face_indices.append(index) + + +func _init(): + command_name = "Move faces" + + + +func do_it(): +# print("cmd move edges- DO IT") + + for block_path in block_map.keys(): + +# print("%s" % block_path) + + var block:CyclopsConvexBlock = builder.get_node(block_path) + var rec:BlockFaceChanges = block_map[block_path] + +# print("rec %s" % rec) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + +# print("init done") + + #var moved_vert_indices:PackedInt32Array + var new_points:PackedVector3Array + var new_sel_centroids:PackedVector3Array + var moved_vert_indices:Array[int] = [] + for face_index in rec.face_indices: + var f:ConvexVolume.FaceInfo = vol.faces[face_index] + var centroid:Vector3 = f.get_centroid() +# var v0:ConvexVolume.VertexInfo = vol.vertices[e.start_index] +# var v1:ConvexVolume.VertexInfo = vol.vertices[e.end_index] + if f.selected: + new_sel_centroids.append(centroid + move_offset) + + for v_idx in f.vertex_indices: + if !moved_vert_indices.has(v_idx): + new_points.append(vol.vertices[v_idx].point + move_offset) + moved_vert_indices.append(v_idx) + else: + for v_idx in f.vertex_indices: + if !moved_vert_indices.has(v_idx): + new_points.append(vol.vertices[v_idx].point + move_offset) + moved_vert_indices.append(v_idx) + + for v_idx in vol.vertices.size(): + if !moved_vert_indices.has(v_idx): + new_points.append(vol.vertices[v_idx].point) + #print("new points_ %s" % new_points) + + var new_vol:ConvexVolume = ConvexVolume.new() + new_vol.init_from_points(new_points) + + new_vol.copy_face_attributes(vol) + #print("new init done") + + #Copy selection data + for f_idx in new_vol.faces.size(): + var f_new:ConvexVolume.FaceInfo = new_vol.faces[f_idx] + var centroid:Vector3 = f_new.get_centroid() +# print ("vol point %s " % v1.point) + if new_sel_centroids.has(centroid): +# print("set sel") + f_new.selected = true + + block.block_data = new_vol.to_convex_block_data() + + +func undo_it(): + for block_path in block_map.keys(): + var rec:BlockFaceChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = rec.tracked_block_data diff --git a/addons/cyclops_level_builder/commands/cmd_move_vertices.gd b/addons/cyclops_level_builder/commands/cmd_move_vertices.gd new file mode 100644 index 0000000..9c8801f --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_move_vertices.gd @@ -0,0 +1,105 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandMoveVertices +extends CyclopsCommand + +class BlockVertexChanges extends RefCounted: + var block_path:NodePath + var vertex_indices:Array[int] = [] + var tracked_block_data:ConvexBlockData + +#Public +var move_offset:Vector3 = Vector3.ZERO + +#Private +var block_map:Dictionary = {} + + +func add_vertex(block_path:NodePath, index:int): + add_vertices(block_path, [index]) + +func add_vertices(block_path:NodePath, indices:Array[int]): +# print("adding vertex %s %s" % [block_path, indices]) + var changes:BlockVertexChanges + if block_map.has(block_path): + changes = block_map[block_path] + else: + changes = BlockVertexChanges.new() + changes.block_path = block_path + var block:CyclopsConvexBlock = builder.get_node(block_path) + changes.tracked_block_data = block.block_data + block_map[block_path] = changes + + for index in indices: + if !changes.vertex_indices.has(index): + changes.vertex_indices.append(index) + +func _init(): + command_name = "Move vertices" + +func do_it(): +# print("move verts do_it") + for block_path in block_map.keys(): + + var block:CyclopsConvexBlock = builder.get_node(block_path) + var rec:BlockVertexChanges = block_map[block_path] + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + +# print("rec.vertex_indices %s" % rec.vertex_indices) +# print("move_offset %s" % move_offset) + var selected_points:PackedVector3Array + var new_points:PackedVector3Array + for v_idx in vol.vertices.size(): + if rec.vertex_indices.has(v_idx): + var p:Vector3 = vol.vertices[v_idx].point + move_offset + new_points.append(p) + selected_points.append(p) + else: + new_points.append(vol.vertices[v_idx].point) + + + var new_vol:ConvexVolume = ConvexVolume.new() + new_vol.init_from_points(new_points) + + new_vol.copy_face_attributes(vol) + + for v_idx in new_vol.vertices.size(): + var v:ConvexVolume.VertexInfo = new_vol.vertices[v_idx] +# print ("vol point %s " % v.point) + if selected_points.has(v.point): +# print("set sel") + v.selected = true + + block.block_data = new_vol.to_convex_block_data() + + +func undo_it(): +# print("move verts undo_it") + for block_path in block_map.keys(): + var rec:BlockVertexChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = rec.tracked_block_data diff --git a/addons/cyclops_level_builder/commands/cmd_select_blocks.gd b/addons/cyclops_level_builder/commands/cmd_select_blocks.gd new file mode 100644 index 0000000..13318e4 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_select_blocks.gd @@ -0,0 +1,135 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandSelectBlocks +extends CyclopsCommand + +#Public +var selection_type:Selection.Type = Selection.Type.REPLACE + +var block_paths:Array[NodePath] + +#Private +var tracked_selected_blocks:Array[NodePath] +var tracked_active_blocks:Array[NodePath] + + +func _init(): + command_name = "Select blocks" + +func will_change_anything()->bool: + + var active_path:NodePath + if !block_paths.is_empty(): + active_path = block_paths[0] + + for child in builder.active_node.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + var path:NodePath = block.get_path() + + match selection_type: + Selection.Type.REPLACE: + if block.selected != block_paths.has(path): + return true + + if block.active != (path == active_path): + return true + + Selection.Type.ADD: + if block_paths.has(path): + if !block.selected: + return true + if block.active != (path == active_path): + return true + + Selection.Type.SUBTRACT: + if block_paths.has(path): + if block.selected: + return true + + Selection.Type.TOGGLE: + if !block_paths.is_empty(): + return true + + return false + + +func do_it(): +# print("sel verts do_it") + + #Cache state + tracked_selected_blocks.clear() + tracked_active_blocks.clear() + + for child in builder.active_node.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + tracked_selected_blocks.append(block.get_path()) + if block.active: + tracked_active_blocks.append(block.get_path()) + + #Do selection + var active_path:NodePath + if !block_paths.is_empty(): + active_path = block_paths[0] + + for child in builder.active_node.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + var path:NodePath = block.get_path() + + match selection_type: + Selection.Type.REPLACE: + block.selected = block_paths.has(path) + block.active = path == active_path + Selection.Type.ADD: + if block_paths.has(path): + block.selected = true + block.active = path == active_path + Selection.Type.SUBTRACT: + if block_paths.has(path): + block.selected = false + block.active = false + Selection.Type.TOGGLE: + block.active = path == active_path + if block_paths.has(path): + block.selected = !block.selected + if !block.selected: + block.active = false + + builder.selection_changed.emit() + +func undo_it(): + + for child in builder.active_node.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + var path:NodePath = block.get_path() + + block.selected = tracked_selected_blocks.has(path) + block.active = tracked_active_blocks.has(path) + + builder.selection_changed.emit() diff --git a/addons/cyclops_level_builder/commands/cmd_select_edges.gd b/addons/cyclops_level_builder/commands/cmd_select_edges.gd new file mode 100644 index 0000000..4bd7e8f --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_select_edges.gd @@ -0,0 +1,189 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandSelectEdges +extends CyclopsCommand + +class BlockEdgeChanges extends RefCounted: + var block_path:NodePath + var edge_indices:Array[int] = [] + var tracked_block_data:ConvexBlockData + +#Public +var selection_type:Selection.Type = Selection.Type.REPLACE + +#Private +var block_map:Dictionary = {} + + +func add_edge(block_path:NodePath, index:int): + add_edges(block_path, [index]) + +func add_edges(block_path:NodePath, indices:Array[int]): + var changes:BlockEdgeChanges + if block_map.has(block_path): + changes = block_map[block_path] + else: + changes = BlockEdgeChanges.new() + changes.block_path = block_path + var block:CyclopsConvexBlock = builder.get_node(block_path) + changes.tracked_block_data = block.block_data + block_map[block_path] = changes + + for index in indices: + if !changes.edge_indices.has(index): + changes.edge_indices.append(index) + + +func _init(): + command_name = "Select edges" + +func will_change_anything()->bool: + for block_path in block_map.keys(): + #print("path %s" % node_path) + + var rec:BlockEdgeChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + + if !rec.edge_indices.is_empty(): + if vol.active_edge != rec.edge_indices[0]: + return true + + match selection_type: + Selection.Type.REPLACE: + for e_idx in vol.edges.size(): + var e:ConvexVolume.EdgeInfo = vol.edges[e_idx] + if e.selected != rec.edge_indices.has(e_idx): + #print("will change SREP") + return true + Selection.Type.ADD: + for e_idx in rec.edge_indices: + var e:ConvexVolume.EdgeInfo = vol.edges[e_idx] + if rec.edge_indices.has(e_idx): + if !e.selected: + #print("will change ADD") + return true + Selection.Type.SUBTRACT: + for e_idx in rec.edge_indices: + var e:ConvexVolume.EdgeInfo = vol.edges[e_idx] + if rec.edge_indices.has(e_idx): + if e.selected: + #print("will change SUB") + return true + Selection.Type.TOGGLE: + #print("will change TOG") + return true + + return false + +func do_it(): +# print("sel edges do_it") + + for block_path in block_map.keys(): +# print("path %s" % block_path) + + var rec:BlockEdgeChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + + if !rec.edge_indices.is_empty(): + var active_index:int = rec.edge_indices[0] + match selection_type: + Selection.Type.REPLACE: + vol.active_edge = active_index + Selection.Type.ADD: + vol.active_edge = active_index + Selection.Type.SUBTRACT: + if rec.edge_indices.has(vol.active_edge): + vol.active_edge = -1 + Selection.Type.TOGGLE: + if rec.edge_indices.has(vol.active_edge): + vol.active_edge = -1 + elif !vol.edges[active_index].selected: + vol.active_edge = active_index + + match selection_type: + Selection.Type.REPLACE: + for e_idx in vol.edges.size(): + var e:ConvexVolume.EdgeInfo = vol.edges[e_idx] + e.selected = rec.edge_indices.has(e_idx) + + Selection.Type.ADD: + for e_idx in vol.edges.size(): + var e:ConvexVolume.EdgeInfo = vol.edges[e_idx] + if rec.edge_indices.has(e_idx): + e.selected = true + + Selection.Type.SUBTRACT: + for e_idx in vol.edges.size(): + var e:ConvexVolume.EdgeInfo = vol.edges[e_idx] + if rec.edge_indices.has(e_idx): + e.selected = false + + Selection.Type.TOGGLE: + for e_idx in vol.edges.size(): + var e:ConvexVolume.EdgeInfo = vol.edges[e_idx] + if rec.edge_indices.has(e_idx): + #print("flipping %s" % e.selected) + e.selected = !e.selected + + if vol.active_edge != -1: + if vol.active_edge >= vol.edges.size() || !vol.edges[vol.active_edge].selected: + vol.active_edge = -1 + + #Synchronize vertex & face selection + #print("synchronizing verts") +# var selected_verts:Array[int] = [] +# for e in vol.edges: +# if e.selected: +# for v_idx in [e.start_index, e.end_index]: +# if !selected_verts.has(v_idx): +# #print("selecting vert %s" % v_idx) +# selected_verts.append(v_idx) +# for v_idx in vol.vertices.size(): +# vol.vertices[v_idx].selected = selected_verts.has(v_idx) +# vol.update_edge_and_face_selection_from_vertices() + + block.block_data = vol.to_convex_block_data() + + builder.selection_changed.emit() + +func undo_it(): +# print("sel verts undo_it") + #print("sel vert undo_it()") + for block_path in block_map.keys(): + var rec:BlockEdgeChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = rec.tracked_block_data + + builder.selection_changed.emit() + + + + diff --git a/addons/cyclops_level_builder/commands/cmd_select_faces.gd b/addons/cyclops_level_builder/commands/cmd_select_faces.gd new file mode 100644 index 0000000..1d583a1 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_select_faces.gd @@ -0,0 +1,180 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandSelectFaces +extends CyclopsCommand + +class BlockFaceChanges extends RefCounted: + var block_path:NodePath + var face_indices:Array[int] = [] + var tracked_block_data:ConvexBlockData + +#Public +var selection_type:Selection.Type = Selection.Type.REPLACE + +#Private +var block_map:Dictionary = {} + +func add_face(block_path:NodePath, index:int): + add_faces(block_path, [index]) + +func add_faces(block_path:NodePath, indices:Array[int]): + var changes:BlockFaceChanges + if block_map.has(block_path): + changes = block_map[block_path] + else: + changes = BlockFaceChanges.new() + changes.block_path = block_path + var block:CyclopsConvexBlock = builder.get_node(block_path) + changes.tracked_block_data = block.block_data + block_map[block_path] = changes + + for index in indices: + if !changes.face_indices.has(index): + changes.face_indices.append(index) + + +func _init(): + command_name = "Select faces" + +func will_change_anything()->bool: + for block_path in block_map.keys(): + #print("path %s" % node_path) + + var rec:BlockFaceChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + +# var active_idx:int = -1 + if !rec.face_indices.is_empty(): + if vol.active_face != rec.face_indices[0]: + return true + + match selection_type: + Selection.Type.REPLACE: + for f_idx in vol.faces.size(): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + if f.selected != rec.face_indices.has(f_idx): + return true + Selection.Type.ADD: + for f_idx in vol.faces.size(): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + if rec.face_indices.has(f_idx): + if !f.selected: + return true + Selection.Type.SUBTRACT: + for f_idx in vol.faces.size(): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + if rec.face_indices.has(f_idx): + if f.selected: + return true + Selection.Type.TOGGLE: + return true + + return false + +func do_it(): + #print("sel verts do_it") + #print("sel vert do_it()") + for block_path in block_map.keys(): +# print("path %s" % block_path) + + var rec:BlockFaceChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + if !rec.face_indices.is_empty(): + var active_index:int = rec.face_indices[0] + match selection_type: + Selection.Type.REPLACE: + vol.active_face = active_index + Selection.Type.ADD: + vol.active_face = active_index + Selection.Type.SUBTRACT: + if rec.face_indices.has(vol.active_face): + vol.active_face = -1 + Selection.Type.TOGGLE: + if rec.face_indices.has(vol.active_face): + vol.active_face = -1 + elif !vol.faces[active_index].selected: + vol.active_face = active_index + + +# print("face active index %s" % active_idx) + + match selection_type: + Selection.Type.REPLACE: + for f_idx in vol.faces.size(): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + f.selected = rec.face_indices.has(f_idx) + + Selection.Type.ADD: + for f_idx in vol.faces.size(): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + if rec.face_indices.has(f_idx): + f.selected = true + + Selection.Type.SUBTRACT: + for f_idx in vol.faces.size(): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + if rec.face_indices.has(f_idx): + f.selected = false + + Selection.Type.TOGGLE: + for f_idx in vol.faces.size(): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + if rec.face_indices.has(f_idx): + f.selected = !f.selected + + if vol.active_face != -1: + if vol.active_face >= vol.faces.size() || !vol.faces[vol.active_face].selected: + vol.active_face = -1 + + + #Synchronize edge & vertex selection +# var selected_verts:Array[int] = [] +# for f in vol.faces: +# if f.selected: +# for v_idx in f.vertex_indices: +# if !selected_verts.has(v_idx): +# selected_verts.append(v_idx) +# for v_idx in vol.vertices.size(): +# vol.vertices[v_idx].selected = selected_verts.has(v_idx) +# vol.update_edge_and_face_selection_from_vertices() + + block.block_data = vol.to_convex_block_data() + builder.selection_changed.emit() + +func undo_it(): +# print("undo_it() select faces") + for block_path in block_map.keys(): + var rec:BlockFaceChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = rec.tracked_block_data + + builder.selection_changed.emit() + diff --git a/addons/cyclops_level_builder/commands/cmd_select_vertices.gd b/addons/cyclops_level_builder/commands/cmd_select_vertices.gd new file mode 100644 index 0000000..99c51a9 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_select_vertices.gd @@ -0,0 +1,167 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandSelectVertices +extends CyclopsCommand + +class BlockVertexChanges extends RefCounted: + var block_path:NodePath + var vertex_indices:Array[int] = [] + var tracked_block_data:ConvexBlockData + +#Public +var selection_type:Selection.Type = Selection.Type.REPLACE + +#Private +var block_map:Dictionary = {} + + + + +func add_vertex(block_path:NodePath, index:int): + add_vertices(block_path, [index]) + +func add_vertices(block_path:NodePath, indices:Array[int]): + var changes:BlockVertexChanges + if block_map.has(block_path): + changes = block_map[block_path] + else: + changes = BlockVertexChanges.new() + changes.block_path = block_path + var block:CyclopsConvexBlock = builder.get_node(block_path) + changes.tracked_block_data = block.block_data + block_map[block_path] = changes + + for index in indices: + if !changes.vertex_indices.has(index): + changes.vertex_indices.append(index) + + +func _init(): + command_name = "Select vertices" + + +func will_change_anything()->bool: + for block_path in block_map.keys(): + #print("path %s" % node_path) + + var rec:BlockVertexChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + + if !rec.vertex_indices.is_empty(): + if vol.active_vertex != rec.vertex_indices[0]: + return true + + match selection_type: + Selection.Type.REPLACE: + for v_idx in vol.vertices.size(): + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + if v.selected != rec.vertex_indices.has(v_idx): + return true + Selection.Type.ADD: + for v_idx in rec.vertex_indices: + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + if rec.vertex_indices.has(v_idx): + if !v.selected: + return true + Selection.Type.SUBTRACT: + for v_idx in rec.vertex_indices: + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + if rec.vertex_indices.has(v_idx): + if v.selected: + return true + Selection.Type.TOGGLE: + return true + + return false + + +func do_it(): +# print("sel verts do_it") + for block_path in block_map.keys(): + #print("path %s" % node_path) + + var rec:BlockVertexChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + + if !rec.vertex_indices.is_empty(): + var active_index:int = rec.vertex_indices[0] + match selection_type: + Selection.Type.REPLACE: + vol.active_vertex = active_index + Selection.Type.ADD: + vol.active_vertex = active_index + Selection.Type.SUBTRACT: + if rec.vertex_indices.has(vol.active_vertex): + vol.active_vertex = -1 + Selection.Type.TOGGLE: + if rec.vertex_indices.has(vol.active_vertex): + vol.active_vertex = -1 + elif !vol.vertices[active_index].selected: + vol.active_vertex = active_index + + match selection_type: + Selection.Type.REPLACE: + for v_idx in vol.vertices.size(): + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + v.selected = rec.vertex_indices.has(v_idx) + + Selection.Type.ADD: + for v_idx in vol.vertices.size(): + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + if rec.vertex_indices.has(v_idx): + v.selected = true + + Selection.Type.SUBTRACT: + for v_idx in vol.vertices.size(): + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + if rec.vertex_indices.has(v_idx): + v.selected = false + + Selection.Type.TOGGLE: + for v_idx in vol.vertices.size(): + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + if rec.vertex_indices.has(v_idx): + v.selected = !v.selected + + vol.update_edge_and_face_selection_from_vertices() + block.block_data = vol.to_convex_block_data() + + builder.selection_changed.emit() + +func undo_it(): +# print("sel verts undo_it") + #print("sel vert undo_it()") + for block_path in block_map.keys(): + var rec:BlockVertexChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = rec.tracked_block_data + + builder.selection_changed.emit() diff --git a/addons/cyclops_level_builder/commands/cmd_set_material.gd b/addons/cyclops_level_builder/commands/cmd_set_material.gd new file mode 100644 index 0000000..d1ac8a4 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_set_material.gd @@ -0,0 +1,153 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandSetMaterial +extends CyclopsCommand + +class Target extends RefCounted: + var block_path:NodePath + var face_indices:PackedInt32Array + +class BlockCache extends RefCounted: + var path:NodePath + var data:ConvexBlockData + var materials:Array[Material] + +#Public +var material_path:String + +#Private +var target_list:Array[Target] = [] + +var cache_list:Array[BlockCache] = [] + +func add_target(block_path:NodePath, face_indices:PackedInt32Array): +# print("add target %s %s" % [block_path.get_name(block_path.get_name_count() - 1), face_indices]) + var target:Target = Target.new() + target.block_path = block_path + target.face_indices = face_indices + + target_list.append(target) + +func make_cache(): + cache_list = [] + + for t in target_list: + var cache:BlockCache = BlockCache.new() + var block:CyclopsConvexBlock = builder.get_node(t.block_path) + + cache.path = block.get_path() + cache.data = block.block_data + cache.materials = block.materials.duplicate() + + cache_list.append(cache) + +func will_change_anything()->bool: + for t in target_list: + if !t.face_indices.is_empty(): + return true + return false + +func _init(): + command_name = "Set material" + +func do_it(): + make_cache() + +# print("cmd set material %s" % material_path) + for t in target_list: + var block:CyclopsConvexBlock = builder.get_node(t.block_path) + + var data:ConvexBlockData = block.block_data + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(data) + + var mat_list:Array[Material] = block.materials.duplicate() +# print("start mat list") +# for m in mat_list: +# print("cur mat %s" % "?" if m == null else m.resource_path) + + var target_material:Material + for m in mat_list: + if m.resource_path == material_path: + target_material = m + break + if !target_material: + target_material = load(material_path) + mat_list.append(target_material) + +# print("target mat list") +# for m in mat_list: +# print("mat %s" % "?" if m == null else m.resource_path) + + var remap_face_idx_to_mat:Array[Material] = [] + + var ctl_mesh:ConvexVolume = ConvexVolume.new() + ctl_mesh.init_from_convex_block_data(block.control_mesh.to_convex_block_data()) + + for f_idx in ctl_mesh.faces.size(): + var f:ConvexVolume.FaceInfo = ctl_mesh.faces[f_idx] + + if t.face_indices.has(f_idx): + remap_face_idx_to_mat.append(target_material) + elif f.material_id >= 0 && f.material_id < block.materials.size(): + remap_face_idx_to_mat.append(block.materials[f.material_id]) + else: + remap_face_idx_to_mat.append(null) + +# print("remap faceidx to mat") +# for m in remap_face_idx_to_mat: +# print("mat %s" % "?" if m == null else m.resource_path) + + #Reduce material list, discarding unused materials + var mat_list_reduced:Array[Material] + for m in remap_face_idx_to_mat: + if m != null && !mat_list_reduced.has(m): + mat_list_reduced.append(m) + +# print("mat_list_reduced") +# for m in mat_list_reduced: +# print("mat %s" % "?" if m == null else m.resource_path) + + #Set new face materials using new material ids + for f_idx in remap_face_idx_to_mat.size(): + #print("face_idx %s" % f_idx) + var face:ConvexVolume.FaceInfo = ctl_mesh.faces[f_idx] + var mat = remap_face_idx_to_mat[f_idx] + #print("mat %s" % "?" if mat == null else mat.resource_path) + #print("has %s" % mat_list_reduced.has(mat)) + #print("find %s" % mat_list_reduced.find(mat)) + + face.material_id = -1 if mat == null else mat_list_reduced.find(mat) + #print("face.material_id %s" % face.material_id) + + block.materials = mat_list_reduced + block.block_data = ctl_mesh.to_convex_block_data() + +func undo_it(): + for cache in cache_list: + var block:CyclopsConvexBlock = builder.get_node(cache.path) + block.materials = cache.materials.duplicate() + block.block_data = cache.data + diff --git a/addons/cyclops_level_builder/commands/cmd_set_uv_transform.gd b/addons/cyclops_level_builder/commands/cmd_set_uv_transform.gd new file mode 100644 index 0000000..3dc9078 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_set_uv_transform.gd @@ -0,0 +1,110 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandSetUvTransform +extends CyclopsCommand + + +class BlockFaceChanges extends RefCounted: + var block_path:NodePath + var face_indices:Array[int] = [] + var tracked_block_data:ConvexBlockData + +var uv_transform:Transform2D = Transform2D.IDENTITY + +#Private +var block_map:Dictionary = {} + +func add_face(block_path:NodePath, index:int): + add_faces(block_path, [index]) + +func add_faces(block_path:NodePath, indices:Array[int]): + var changes:BlockFaceChanges + if block_map.has(block_path): + changes = block_map[block_path] + else: + changes = BlockFaceChanges.new() + changes.block_path = block_path + var block:CyclopsConvexBlock = builder.get_node(block_path) + changes.tracked_block_data = block.block_data + block_map[block_path] = changes + + for index in indices: + if !changes.face_indices.has(index): + changes.face_indices.append(index) + + +func _init(): + command_name = "Set Uv Transform" + +func will_change_anything()->bool: + for block_path in block_map.keys(): + + var rec:BlockFaceChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + +# print("face active index %s" % active_idx) + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + + for f_idx in vol.faces.size(): + if rec.face_indices.has(f_idx): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + if f.uv_transform != uv_transform: + return true + + return false + + +func do_it(): + #print("sel verts do_it") + #print("sel vert do_it()") + for block_path in block_map.keys(): +# print("path %s" % block_path) + + var rec:BlockFaceChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + +# print("face active index %s" % active_idx) + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + + for f_idx in vol.faces.size(): + if rec.face_indices.has(f_idx): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + f.uv_transform = uv_transform + + block.block_data = vol.to_convex_block_data() + builder.selection_changed.emit() + + +func undo_it(): +# print("undo_it() select faces") + for block_path in block_map.keys(): + var rec:BlockFaceChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = rec.tracked_block_data + + builder.selection_changed.emit() + diff --git a/addons/cyclops_level_builder/commands/cmd_snap_to_grid.gd b/addons/cyclops_level_builder/commands/cmd_snap_to_grid.gd new file mode 100644 index 0000000..494fa1f --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_snap_to_grid.gd @@ -0,0 +1,82 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandSnapToGrid +extends CyclopsCommand + +class TrackedInfo extends RefCounted: + var data:ConvexBlockData + +var grid_size:float + +#Private +var blocks_to_move:Array[NodePath] +var tracked_block_data:Array[TrackedInfo] + + +func _init(): + command_name = "Snap to grid" + + +#Add blocks to be moved here +func add_block(block_path:NodePath): + blocks_to_move.append(block_path) + + var block:CyclopsConvexBlock = builder.get_node(block_path) + #tracked_blocks.append(block) + var info:TrackedInfo = TrackedInfo.new() + info.data = block.block_data.duplicate() +# info.materials = block.materials + tracked_block_data.append(info) + + +func do_it(): + for i in blocks_to_move.size(): + var block:CyclopsConvexBlock = builder.get_node(blocks_to_move[i]) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(tracked_block_data[i].data) + + var points_new:PackedVector3Array + for v_idx in vol.vertices.size(): + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + var p_snap:Vector3 = MathUtil.snap_to_grid(v.point, grid_size) + points_new.append(p_snap) + + var new_vol:ConvexVolume = ConvexVolume.new() + new_vol.init_from_points(points_new) + + + new_vol.copy_face_attributes(vol) + + block.block_data = new_vol.to_convex_block_data() + +func undo_it(): + for i in blocks_to_move.size(): + var block:CyclopsConvexBlock = builder.get_node(blocks_to_move[i]) + + block.block_data = tracked_block_data[i].data + + + diff --git a/addons/cyclops_level_builder/commands/cmd_transform_blocks.gd b/addons/cyclops_level_builder/commands/cmd_transform_blocks.gd new file mode 100644 index 0000000..ef1789b --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_transform_blocks.gd @@ -0,0 +1,76 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandTransformBlocks +extends CyclopsCommand + +class TrackedInfo extends RefCounted: + var data:ConvexBlockData +# var materials:Array[Material] + +var transform:Transform3D +var lock_uvs:bool = false + +#Private +var blocks_to_move:Array[NodePath] +var tracked_block_data:Array[TrackedInfo] + +func _init(): + command_name = "Transform blocks" + +#Add blocks to be moved here +func add_block(block_path:NodePath): + blocks_to_move.append(block_path) + + var block:CyclopsConvexBlock = builder.get_node(block_path) + #tracked_blocks.append(block) + var info:TrackedInfo = TrackedInfo.new() + info.data = block.block_data.duplicate() +# info.materials = block.materials + tracked_block_data.append(info) + +#Moves all blocks from the start position by this amount +func apply_transform(xform:Transform3D): + for i in blocks_to_move.size(): + var block:CyclopsConvexBlock = builder.get_node(blocks_to_move[i]) + + var ctl_mesh:ConvexVolume = ConvexVolume.new() + ctl_mesh.init_from_convex_block_data(tracked_block_data[i].data) + ctl_mesh.transform(xform, lock_uvs) + var result_data:ConvexBlockData = ctl_mesh.to_convex_block_data() + block.block_data = result_data +# block.materials = tracked_block_data[i].materials + #tracked_blocks[block_idx].block_data = result_data + +func do_it(): +# if blocks_to_move.is_empty(): +# var blocks:Array[CyclopsConvexBlock] = builder.get_selected_blocks() +# for block in blocks: +# add_block(block.get_path()) + + apply_transform(transform) + +func undo_it(): + apply_transform(Transform3D.IDENTITY) + diff --git a/addons/cyclops_level_builder/commands/cyclops_command.gd b/addons/cyclops_level_builder/commands/cyclops_command.gd new file mode 100644 index 0000000..9bc5e0c --- /dev/null +++ b/addons/cyclops_level_builder/commands/cyclops_command.gd @@ -0,0 +1,43 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CyclopsCommand +extends RefCounted + +var command_name:String = "" +var builder:CyclopsLevelBuilder + +func add_to_undo_manager(undo_manager:EditorUndoRedoManager): + undo_manager.create_action(command_name, UndoRedo.MERGE_DISABLE) + undo_manager.add_do_method(self, "do_it") + undo_manager.add_undo_method(self, "undo_it") + + undo_manager.commit_action() + +func do_it()->void: + pass + +func undo_it()->void: + pass + diff --git a/addons/cyclops_level_builder/controls/numeric_line_edit.gd b/addons/cyclops_level_builder/controls/numeric_line_edit.gd new file mode 100644 index 0000000..90f281f --- /dev/null +++ b/addons/cyclops_level_builder/controls/numeric_line_edit.gd @@ -0,0 +1,125 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends PanelContainer +class_name NumbericLineEdit + +signal value_changed(value) + +@export var value:float: + get: + return value + set(v): + if value == v: + return + value = v + dirty = true + +@export var snap_size:float = 1 +var dirty:bool = true + +enum State{ IDLE, READY, DRAGGING, TEXT_EDIT } +var state:State = State.IDLE + +var mouse_down_pos:Vector2 +var drag_start_radius:float = 4 +var value_start_drag:float + +# Called when the node enters the scene tree for the first time. +func _ready(): +# text = "%.4f" % value +# $HBoxContainer/LineEdit.text = "%s" % value +# $HBoxContainer/Label.text = "%s" % value + $HBoxContainer/LineEdit.visible = false + pass + +func _process(delta): + if dirty: + $HBoxContainer/LineEdit.text = format_number(value) + $HBoxContainer/Label.text = format_number(value) + dirty = false + +func format_number(val:float)->String: + var text:String = "%.5f" % val + var idx:int = text.findn(".") + if idx != -1: + text = text.rstrip("0") + if text.right(1) == ".": + text = text.left(-1) + return text + + +func _gui_input(event): + if event is InputEventMouseButton: + var e:InputEventMouseButton = event + if e.is_pressed(): + if state == State.IDLE: + mouse_down_pos = e.position + state = State.READY + else: + if state == State.READY: + $HBoxContainer/LineEdit.visible = true + $HBoxContainer/Label.visible = false + state = State.TEXT_EDIT + elif state == State.DRAGGING: + state = State.IDLE + + + accept_event() + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + if state == State.READY: + if e.position.distance_to(mouse_down_pos) >= drag_start_radius: + state = State.DRAGGING + value_start_drag = value + + elif state == State.DRAGGING: + var offset = e.position.x - mouse_down_pos.x + var new_value = value_start_drag + (offset * snap_size / 20.0) + #print("-new_value %s" % new_value) + new_value = ceil(new_value / snap_size) * snap_size + + #print("new_value %s" % new_value) + + if value != new_value: + value = new_value + value_changed.emit(value) + dirty = true + +func _on_line_edit_text_submitted(new_text): + var regex = RegEx.new() + regex.compile("^[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)$") + var result:RegExMatch = regex.search(new_text) + if result: +# print("found match") + value = float(new_text) + value_changed.emit(value) + + dirty = true + state = State.IDLE + $HBoxContainer/LineEdit.visible = false + $HBoxContainer/Label.visible = true +# text = "%s" % value +# print("text changed2 %s" % text) diff --git a/addons/cyclops_level_builder/controls/numeric_line_edit.tscn b/addons/cyclops_level_builder/controls/numeric_line_edit.tscn new file mode 100644 index 0000000..c85c785 --- /dev/null +++ b/addons/cyclops_level_builder/controls/numeric_line_edit.tscn @@ -0,0 +1,26 @@ +[gd_scene load_steps=2 format=3 uid="uid://diibmlqy1mpqb"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/controls/numeric_line_edit.gd" id="1_u8bpo"] + +[node name="PanelContainer" type="PanelContainer"] +offset_right = 476.0 +offset_bottom = 40.0 +script = ExtResource("1_u8bpo") +snap_size = 0.125 + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 + +[node name="LineEdit" type="LineEdit" parent="HBoxContainer"] +visible = false +layout_mode = 2 +size_flags_horizontal = 3 +text = "0" +select_all_on_focus = true + +[node name="Label" type="Label" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "0" + +[connection signal="text_submitted" from="HBoxContainer/LineEdit" to="." method="_on_line_edit_text_submitted"] diff --git a/addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.gd b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.gd new file mode 100644 index 0000000..47ee1c5 --- /dev/null +++ b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.gd @@ -0,0 +1,66 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends CheckBox +class_name LineEditorBool + +var resource:Resource: + get: + return resource + set(value): + resource = value + dirty = true + +var prop_name:String: + get: + return prop_name + set(value): + prop_name = value + dirty = true + +var dirty = true + +func update_from_resource(): + if resource: + var result = resource.get(prop_name) + if result != null: + button_pressed = result + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + if dirty: + update_from_resource() + dirty = false + + +func _on_toggled(button_pressed): + if resource: + print("prop_name %s" % prop_name) + print("button_pressed %s" % button_pressed) + resource.set(prop_name, button_pressed) diff --git a/addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.tscn b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.tscn new file mode 100644 index 0000000..9ece333 --- /dev/null +++ b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=2 format=3 uid="uid://dpncabeqiv1xo"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.gd" id="1_sn3qq"] + +[node name="CheckBox" type="CheckBox"] +offset_right = 24.0 +offset_bottom = 24.0 +script = ExtResource("1_sn3qq") + +[connection signal="toggled" from="." to="." method="_on_toggled"] diff --git a/addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.gd b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.gd new file mode 100644 index 0000000..c3eea2e --- /dev/null +++ b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.gd @@ -0,0 +1,65 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends SpinBox +class_name LineEditorFloat + + +var resource:Resource: + get: + return resource + set(value): + resource = value + dirty = true + +var prop_name:String: + get: + return prop_name + set(value): + prop_name = value + dirty = true + +var dirty = true + +func update_from_resource(): + if resource: + var result = resource.get(prop_name) + if result != null: + value = result + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + if dirty: + update_from_resource() + dirty = false + + +func _on_value_changed(value): + if resource: + resource.set(prop_name, value) diff --git a/addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.tscn b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.tscn new file mode 100644 index 0000000..2ce2af2 --- /dev/null +++ b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.tscn @@ -0,0 +1,11 @@ +[gd_scene load_steps=2 format=3 uid="uid://dg45e7tw7ttu3"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.gd" id="1_o1hmb"] + +[node name="SpinBox" type="SpinBox"] +offset_right = 83.0625 +offset_bottom = 31.0 +step = 0.001 +script = ExtResource("1_o1hmb") + +[connection signal="value_changed" from="." to="." method="_on_value_changed"] diff --git a/addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.gd b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.gd new file mode 100644 index 0000000..2659e91 --- /dev/null +++ b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.gd @@ -0,0 +1,71 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends SpinBox +class_name LineEditorInt + +var resource:Resource: + get: + return resource + set(value): + resource = value + dirty = true + +var prop_name:String: + get: + return prop_name + set(value): + prop_name = value + dirty = true + +var dirty = true + +func update_from_resource(): + #print("update_from_resource()") + if resource: + #print("resource %s" % resource) + #print("prop_name %s" % prop_name) + var result = resource.get(prop_name) + #print("result %s" % result) + if result != null: + value = result + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + if dirty: + update_from_resource() + dirty = false + + +func _on_value_changed(value): + print("_on_value_changed(value)") + if resource: + print("prop_name %s" % prop_name) + print("value %s" % value) + resource.set(prop_name, value) diff --git a/addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.tscn b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.tscn new file mode 100644 index 0000000..35e8ef9 --- /dev/null +++ b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=2 format=3 uid="uid://dh6frljlp7oqe"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.gd" id="1_ryygx"] + +[node name="SpinBox" type="SpinBox"] +offset_right = 83.0625 +offset_bottom = 40.0 +script = ExtResource("1_ryygx") + +[connection signal="value_changed" from="." to="." method="_on_value_changed"] diff --git a/addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.gd b/addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.gd new file mode 100644 index 0000000..16de2ba --- /dev/null +++ b/addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.gd @@ -0,0 +1,86 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Control +class_name ResourceInspector + +@export var target:Resource: + get: + return target + set(value): + target = value + build() + +func add_label(name:String): + var label:Label = Label.new() + label.text = name + $GridContainer.add_child(label) + +func build(): + for child in $GridContainer.get_children(): + $GridContainer.remove_child(child) + + if !target: + return + + for prop_dict in target.get_property_list(): + var prop_name:String = prop_dict["name"] +# prop_dict["class_name"] + + var type:Variant.Type = prop_dict["type"] + match type: + TYPE_BOOL: + add_label(prop_name) + + var editor:LineEditorBool = preload("res://addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.tscn").instantiate() + editor.resource = target + editor.prop_name = prop_name + $GridContainer.add_child(editor) + + TYPE_INT: + add_label(prop_name) + + var editor:LineEditorInt = preload("res://addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.tscn").instantiate() + editor.resource = target + editor.prop_name = prop_name + $GridContainer.add_child(editor) + + TYPE_FLOAT: + add_label(prop_name) + + var editor:LineEditorFloat = preload("res://addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.tscn").instantiate() + editor.resource = target + editor.prop_name = prop_name + $GridContainer.add_child(editor) + + pass + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass diff --git a/addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.tscn b/addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.tscn new file mode 100644 index 0000000..043660b --- /dev/null +++ b/addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=2 format=3 uid="uid://c2484sv0ymy2e"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.gd" id="1_m3yhx"] + +[node name="object_inspector" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_m3yhx") + +[node name="GridContainer" type="GridContainer" parent="."] +layout_mode = 0 +offset_right = 40.0 +offset_bottom = 40.0 +columns = 2 diff --git a/addons/cyclops_level_builder/cyclops_global_scene.gd b/addons/cyclops_level_builder/cyclops_global_scene.gd new file mode 100644 index 0000000..eaf9719 --- /dev/null +++ b/addons/cyclops_level_builder/cyclops_global_scene.gd @@ -0,0 +1,250 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Node3D +class_name CyclopsGlobalScene + +@export var selection_color:Color = Color(1, .5, .5, 1) +@export var default_material:Material = preload("res://addons/cyclops_level_builder/materials/grid.tres") +@export var tool_edit_active_material:Material = preload("res://addons/cyclops_level_builder/materials/tool_edit_active_material.tres") +@export var tool_edit_active_fill_material:Material = preload("res://addons/cyclops_level_builder/materials/tool_edit_active_fill_material.tres") +@export var tool_edit_selected_material:Material = preload("res://addons/cyclops_level_builder/materials/tool_edit_selected_material.tres") +@export var tool_edit_selected_fill_material:Material = preload("res://addons/cyclops_level_builder/materials/tool_edit_selected_fill_material.tres") +@export var tool_edit_unselected_material:Material = preload("res://addons/cyclops_level_builder/materials/tool_edit_unselected_material.tres") +@export var tool_object_active_material:Material = preload("res://addons/cyclops_level_builder/materials/tool_object_active_material.tres") +@export var tool_object_selected_material:Material = preload("res://addons/cyclops_level_builder/materials/tool_object_selected_material.tres") +#@export var outline_material:Material = preload("res://addons/cyclops_level_builder/materials/block_outline_material.tres") + +@export var tool_material:Material = preload("res://addons/cyclops_level_builder/materials/tool_material.tres") +@export var outline_material:Material = preload("res://addons/cyclops_level_builder/materials/outline_material.tres") +#@export var tool_selected_material:Material +#@export var selected_material:Material +var tool_mesh:ImmediateMesh +#var vertex_size:float = .05 + +@export var grid_size:int = 0 + +var unit_sphere:GeometryMesh +var builder:CyclopsLevelBuilder +# +#enum DisplayMode { TEXTURED, WIRE } +#var display_mode:DisplayMode = DisplayMode.TEXTURED + +# Called when the node enters the scene tree for the first time. +func _ready(): + unit_sphere = MathGeometry.unit_sphere() + + tool_mesh = ImmediateMesh.new() + $ToolInstance3D.mesh = tool_mesh + +func draw_line(p0:Vector3, p1:Vector3, mat:Material): + +# var mat:Material = tool_selected_material if selected else tool_material + + tool_mesh.surface_begin(Mesh.PRIMITIVE_LINES, mat) + + tool_mesh.surface_add_vertex(p0) + tool_mesh.surface_add_vertex(p1) + + tool_mesh.surface_end() + +func draw_loop(points:PackedVector3Array, closed:bool = true, mat:Material = null): + if points.is_empty(): + return + + tool_mesh.surface_begin(Mesh.PRIMITIVE_LINE_STRIP, mat) + + for p in points: + tool_mesh.surface_add_vertex(p) + + if closed: + tool_mesh.surface_add_vertex(points[0]) + + tool_mesh.surface_end() + + +func draw_prism(points:PackedVector3Array, extrude:Vector3, mat:Material = null): + for p in points: + draw_vertex(p) + draw_vertex(p + extrude) + + #Bottom loop + tool_mesh.surface_begin(Mesh.PRIMITIVE_LINE_STRIP, mat) + + for p in points: + tool_mesh.surface_add_vertex(p) + + tool_mesh.surface_add_vertex(points[0]) + + tool_mesh.surface_end() + + #Top loop + tool_mesh.surface_begin(Mesh.PRIMITIVE_LINE_STRIP, mat) + + for p in points: + tool_mesh.surface_add_vertex(p + extrude) + + tool_mesh.surface_add_vertex(points[0] + extrude) + + tool_mesh.surface_end() + + #Sides + tool_mesh.surface_begin(Mesh.PRIMITIVE_LINES, mat) + + for p in points: + tool_mesh.surface_add_vertex(p) + tool_mesh.surface_add_vertex(p + extrude) + + tool_mesh.surface_end() + + #$ToolInstance3D.mesh = mesh + + +func draw_triangles(tri_points:PackedVector3Array, mat:Material = null): + tool_mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLES, mat) + + for p in tri_points: + tool_mesh.surface_add_vertex(p) + + tool_mesh.surface_end() + +func draw_rect(start:Vector3, end:Vector3, mat:Material = null): + + var p0:Vector3 = start + var p2:Vector3 = end + var p1:Vector3 = Vector3(p0.x, p0.y, p2.z) + var p3:Vector3 = Vector3(p2.x, p0.y, p0.z) + + draw_vertex(p0, mat) + draw_vertex(p1, mat) + draw_vertex(p2, mat) + draw_vertex(p3, mat) + + tool_mesh.surface_begin(Mesh.PRIMITIVE_LINE_STRIP, mat) + + tool_mesh.surface_add_vertex(p0) + tool_mesh.surface_add_vertex(p1) + tool_mesh.surface_add_vertex(p2) + tool_mesh.surface_add_vertex(p3) + tool_mesh.surface_add_vertex(p0) + + tool_mesh.surface_end() + + #$ToolInstance3D.mesh = tool_mesh + +func clear_tool_mesh(): + #tool_mesh = ImmediateMesh.new() + #$ToolInstance3D.mesh = tool_mesh + tool_mesh.clear_surfaces() + +# Draws the bounding box for the points [p0, p1, p2] +func draw_cube(p0:Vector3, p1:Vector3, p2:Vector3, mat:Material = null): +# print ("draw_cube %s %s %s" % [p0, p1, p2]) + + var bounds:AABB = AABB(p0, Vector3.ZERO) + bounds = bounds.expand(p1) + bounds = bounds.expand(p2) + + var p000:Vector3 = bounds.position + var p111:Vector3 = bounds.end + var p001:Vector3 = Vector3(p000.x, p000.y, p111.z) + var p010:Vector3 = Vector3(p000.x, p111.y, p000.z) + var p011:Vector3 = Vector3(p000.x, p111.y, p111.z) + var p100:Vector3 = Vector3(p111.x, p000.y, p000.z) + var p101:Vector3 = Vector3(p111.x, p000.y, p111.z) + var p110:Vector3 = Vector3(p111.x, p111.y, p000.z) + + draw_vertex(p000, mat) + draw_vertex(p001, mat) + draw_vertex(p010, mat) + draw_vertex(p011, mat) + draw_vertex(p100, mat) + draw_vertex(p101, mat) + draw_vertex(p110, mat) + draw_vertex(p111, mat) + + + tool_mesh.surface_begin(Mesh.PRIMITIVE_LINES, mat) + + tool_mesh.surface_add_vertex(p000) + tool_mesh.surface_add_vertex(p001) + tool_mesh.surface_add_vertex(p000) + tool_mesh.surface_add_vertex(p100) + tool_mesh.surface_add_vertex(p101) + tool_mesh.surface_add_vertex(p001) + tool_mesh.surface_add_vertex(p101) + tool_mesh.surface_add_vertex(p100) + + tool_mesh.surface_add_vertex(p010) + tool_mesh.surface_add_vertex(p011) + tool_mesh.surface_add_vertex(p010) + tool_mesh.surface_add_vertex(p110) + tool_mesh.surface_add_vertex(p111) + tool_mesh.surface_add_vertex(p011) + tool_mesh.surface_add_vertex(p111) + tool_mesh.surface_add_vertex(p110) + + tool_mesh.surface_add_vertex(p000) + tool_mesh.surface_add_vertex(p010) + tool_mesh.surface_add_vertex(p100) + tool_mesh.surface_add_vertex(p110) + tool_mesh.surface_add_vertex(p101) + tool_mesh.surface_add_vertex(p111) + tool_mesh.surface_add_vertex(p001) + tool_mesh.surface_add_vertex(p011) + + tool_mesh.surface_end() + + #$ToolInstance3D.mesh = mesh + +func draw_points(points:PackedVector3Array, mat:Material = null): + for p in points: + draw_vertex(p, mat) + +func draw_vertex(position:Vector3, mat:Material = null): + var xform:Transform3D = Transform3D(Basis.IDENTITY.scaled(Vector3.ONE * builder.handle_point_radius), position) + draw_sphere(xform, mat) + +func draw_sphere(xform:Transform3D = Transform3D.IDENTITY, material:Material = null, segs_lat:int = 6, segs_long:int = 8): + unit_sphere.append_to_immediate_mesh(tool_mesh, material, xform) + + +func draw_selected_blocks(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_node("/root/CyclopsAutoload") + #var mesh:ImmediateMesh = ImmediateMesh.new() + + if builder.active_node is CyclopsBlocks: + var blocks_root:CyclopsBlocks = builder.active_node + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + block.append_mesh_outline(tool_mesh, viewport_camera, blocks_root.global_transform) + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): +# if Engine.is_editor_hint(): +# rebuild_mesh() + pass diff --git a/addons/cyclops_level_builder/cyclops_global_scene.tscn b/addons/cyclops_level_builder/cyclops_global_scene.tscn new file mode 100644 index 0000000..d37c83d --- /dev/null +++ b/addons/cyclops_level_builder/cyclops_global_scene.tscn @@ -0,0 +1,17 @@ +[gd_scene load_steps=4 format=3 uid="uid://4siqre3jhe80"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/cyclops_global_scene.gd" id="1_nu1d3"] + +[sub_resource type="PlaneMesh" id="PlaneMesh_sl0cw"] + +[sub_resource type="ImmediateMesh" id="ImmediateMesh_ey6kk"] + +[node name="CyclopsGlobals" type="Node3D"] +script = ExtResource("1_nu1d3") + +[node name="ControlMesh" type="MeshInstance3D" parent="."] +visible = false +mesh = SubResource("PlaneMesh_sl0cw") + +[node name="ToolInstance3D" type="MeshInstance3D" parent="."] +mesh = SubResource("ImmediateMesh_ey6kk") diff --git a/addons/cyclops_level_builder/cyclops_level_builder.gd b/addons/cyclops_level_builder/cyclops_level_builder.gd new file mode 100644 index 0000000..568af41 --- /dev/null +++ b/addons/cyclops_level_builder/cyclops_level_builder.gd @@ -0,0 +1,225 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends EditorPlugin +class_name CyclopsLevelBuilder + +signal active_node_changed +signal selection_changed + +const AUTOLOAD_NAME = "CyclopsAutoload" + +var material_dock:Control +var uv_editor_dock:Control +var tool_properties_dock:Control +#var sticky_toolbar:StickyToolbar +var editor_toolbar:EditorToolbar +var activated:bool = false + + +var block_create_distance:float = 20 +var tool:CyclopsTool = null +var lock_uvs:bool = false +var tool_overlay_extrude:float = .01 + +var tool_uv_transform:Transform2D +var tool_material_path:String + +var handle_point_radius:float = .05 +var handle_screen_radius:float = 4 + +var drag_start_radius:float = 4 + +enum Mode { OBJECT, EDIT } +var mode:Mode = Mode.OBJECT +enum EditMode { VERTEX, EDGE, FACE } +var edit_mode:EditMode = EditMode.VERTEX + +var display_mode:DisplayMode.Type = DisplayMode.Type.TEXTURED + +#var _active_node:GeometryBrush +var active_node:CyclopsBlocks: + get: + return active_node + set(value): + if active_node != value: + active_node = value + active_node_changed.emit() + +func get_selected_blocks()->Array[CyclopsConvexBlock]: + var result:Array[CyclopsConvexBlock] + + if active_node: + for child in active_node.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if child.selected: + result.append(child) + + return result + +func _get_plugin_name()->String: + return "CyclopsLevelBuilder" + +func _get_plugin_icon()->Texture2D: + return preload("res://addons/cyclops_level_builder/art/cyclops.svg") + +func _enter_tree(): + add_custom_type("CyclopsBlocks", "Node3D", preload("nodes/cyclops_blocks.gd"), preload("nodes/cyclops_blocks_icon.png")) + add_custom_type("CyclopsConvexBlock", "Node", preload("nodes/cyclops_convex_block.gd"), preload("nodes/cyclops_blocks_icon.png")) + add_custom_type("CyclopsConvexBlockBody", "Node", preload("nodes/cyclops_convex_block_body.gd"), preload("nodes/cyclops_blocks_icon.png")) + + add_autoload_singleton(AUTOLOAD_NAME, "res://addons/cyclops_level_builder/cyclops_global_scene.tscn") + + material_dock = preload("res://addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.tscn").instantiate() + material_dock.builder = self + + uv_editor_dock = preload("res://addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.tscn").instantiate() + uv_editor_dock.builder = self + + tool_properties_dock = preload("res://addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.tscn").instantiate() + tool_properties_dock.builder = self + + editor_toolbar = preload("menu/editor_toolbar.tscn").instantiate() + editor_toolbar.editor_plugin = self + +# sticky_toolbar = preload("menu/sticky_toolbar.tscn").instantiate() +# sticky_toolbar.plugin = self +# add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, sticky_toolbar) + + var editor:EditorInterface = get_editor_interface() + var selection:EditorSelection = editor.get_selection() + selection.selection_changed.connect(on_selection_changed) + + update_activation() + + + #Wait until everything is loaded + await get_tree().process_frame + var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + global_scene.builder = self + + switch_to_tool(ToolBlock.new()) + +func find_blocks_root(node:Node)->CyclopsBlocks: + if node is CyclopsBlocks: + return node + if node is CyclopsConvexBlock: + return find_blocks_root(node.get_parent()) + return null + +func update_activation(): + var editor:EditorInterface = get_editor_interface() + var selection:EditorSelection = editor.get_selection() + var nodes:Array[Node] = selection.get_selected_nodes() + if !nodes.is_empty(): + var node:Node = nodes[0] + + var blocks_root:CyclopsBlocks = find_blocks_root(node) + + if blocks_root: + active_node = blocks_root + if !activated: + add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, editor_toolbar) + add_control_to_dock(DOCK_SLOT_RIGHT_BL, material_dock) + add_control_to_dock(DOCK_SLOT_RIGHT_BL, uv_editor_dock) + add_control_to_dock(DOCK_SLOT_RIGHT_BL, tool_properties_dock) + activated = true + else: + if activated: + remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, editor_toolbar) + remove_control_from_docks(material_dock) + remove_control_from_docks(uv_editor_dock) + remove_control_from_docks(tool_properties_dock) + activated = false + else: + active_node = null + +func on_selection_changed(): + update_activation() + +func _exit_tree(): + # Clean-up of the plugin goes here. + remove_autoload_singleton(AUTOLOAD_NAME) + + remove_custom_type("CyclopsBlocks") + remove_custom_type("CyclopsConvexBlock") + remove_custom_type("CyclopsConvexBlockBody") + +# remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, sticky_toolbar) + + if activated: + remove_control_from_docks(material_dock) + remove_control_from_docks(uv_editor_dock) + remove_control_from_docks(tool_properties_dock) + remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, editor_toolbar) + + material_dock.queue_free() + uv_editor_dock.queue_free() + tool_properties_dock.queue_free() + editor_toolbar.queue_free() + +func _handles(object:Object): + return object is CyclopsBlocks or object is CyclopsConvexBlock + +func _forward_3d_draw_over_viewport(viewport_control:Control): + #Draw on top of viweport here + pass + +func _forward_3d_gui_input(viewport_camera:Camera3D, event:InputEvent): + #print("plugin: " + event.as_text()) + + if tool: + var result:bool = tool._gui_input(viewport_camera, event) + tool._draw_tool(viewport_camera) + return EditorPlugin.AFTER_GUI_INPUT_STOP if result else EditorPlugin.AFTER_GUI_INPUT_PASS + + return EditorPlugin.AFTER_GUI_INPUT_PASS + +func _get_state()->Dictionary: + var state:Dictionary = {} + material_dock.save_state(state) + uv_editor_dock.save_state(state) + tool_properties_dock.save_state(state) + return state + +func _set_state(state): + material_dock.load_state(state) + uv_editor_dock.load_state(state) + tool_properties_dock.load_state(state) + +func switch_to_tool(_tool:CyclopsTool): + if tool: + tool._deactivate() + + tool = _tool + + if tool: + tool._activate(self) + var control:Control = tool._get_tool_properties_editor() + tool_properties_dock.set_editor(control) + +func get_global_scene()->CyclopsGlobalScene: + var scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + return scene diff --git a/addons/cyclops_level_builder/doc/Text b/addons/cyclops_level_builder/doc/Text new file mode 100644 index 0000000..4080d17 --- /dev/null +++ b/addons/cyclops_level_builder/doc/Text @@ -0,0 +1,54 @@ +import bpy +import mathutils + +def draw_plane(hessian): + # Extract the plane coefficients from the Hessian form + a, b, c, d = hessian + + # Calculate the normal vector of the plane + normal = mathutils.Vector((a, b, c)) + + # Calculate the point at the center of the plane + point = normal * d + + # Calculate a vector perpendicular to the normal + if abs(normal.z) < 1e-6: + tangent = mathutils.Vector((0, 0, 1)) + else: + tangent = mathutils.Vector((0, 1, -normal.y/normal.z)).normalized() + + binorm = tangent.cross(normal) + + # Create a new mesh object for the point, dot, and line + mesh = bpy.data.meshes.new(name="Plane Center and Normal") + obj = bpy.data.objects.new(name="Plane Object", object_data=mesh) + + # Create the vertices for the point, dot, and line + vertices = [ + point + tangent * 0.1, + point, + point + normal, + point + binorm * 0.1, + ] + + # Create the edges for the line + edges = [ + (0, 1), # Edge from point to start of line + (1, 2) , # Edge for the line + (1, 3) + ] + + # Create the mesh data for the point, dot, and line + mesh.from_pydata(vertices, edges, []) + + # Add the object to the scene + bpy.context.scene.collection.objects.link(obj) + +planes = [(-0.96225, 0.192449, 0.192451, -4.04145), (-0.404079, 0.888975, 0.21551, -3.85222), (-0.703526, -0.502519, -0.502519, -2.31159), (-0.123091, -0.86164, 0.492366, -2.33874), (-0.211079, -0.492518, 0.844317, -3.02547), (0.442326, 0.147442, 0.884652, -2.50651), (0.928279, -0.206284, 0.309426, -1.13456), (0.973329, -0.162221, 0.162222, -1.29777), (0.117041, 0.702247, -0.702247, -3.04307), (-9.6656e-08, 1.35319e-07, -1, -2)] +#planes = [(0, 0, -1, -12), (0, 1, 0, 9)] + +for p in planes: + draw_plane(p) + +#draw_plane((0, 1, 0, 11)) + \ No newline at end of file diff --git a/addons/cyclops_level_builder/doc/create_plane_objects.py b/addons/cyclops_level_builder/doc/create_plane_objects.py new file mode 100644 index 0000000..f28ce53 --- /dev/null +++ b/addons/cyclops_level_builder/doc/create_plane_objects.py @@ -0,0 +1,34 @@ +import bpy +import mathutils + +def create_plane_on_plane(p0): + # Extract the normal and distance from the Hessian form of the plane + normal = mathutils.Vector(p0[:3]) + distance = p0[3] + + # Calculate the center of the plane + center = normal * distance + + # Create a new plane object + bpy.ops.mesh.primitive_plane_add() + obj0 = bpy.context.active_object + + # Set the plane's origin to the center of the plane + obj0.location = center + + # Calculate the rotation needed to align the z-axis with the plane normal + z_axis = mathutils.Vector((0, 0, 1)) + angle = normal.angle(z_axis, 0) + axis = z_axis.cross(normal) + euler = mathutils.Matrix.Rotation(angle, 4, axis).to_euler() + obj0.rotation_euler = euler + + + return obj0 + + +planes = [(0.274721, 9.82474e-08, -0.961524, -8.10427), (-1, -3.57626e-07, -2.38418e-07, -2), (0.904534, 0.301512, 0.301512, -1.50755), (0, 1, 0, 3), (5.08628e-06, -1, -2.75509e-06, -7.00003), (0.727606, -0.485071, -0.485072, -8.48875), (0.465341, -0.426562, -0.775566, -9.03536), (-0.369799, -0.0924517, 0.924501, 1.75654), (3.19872e-07, -0.447214, 0.894427, -0.447216), (-0.957704, -0.239427, 0.159618, -2.15484)] +for p in planes: + create_plane_on_plane(p) + +#create_plane_on_plane((0.274721, 9.82474e-08, -0.961524, -8.10427)) diff --git a/addons/cyclops_level_builder/doc/draw_plane.py b/addons/cyclops_level_builder/doc/draw_plane.py new file mode 100644 index 0000000..55eb8fb --- /dev/null +++ b/addons/cyclops_level_builder/doc/draw_plane.py @@ -0,0 +1,35 @@ +import bpy +import mathutils + +def draw_plane(hessian): + # Extract the plane coefficients from the Hessian form + a, b, c, d = hessian + + # Calculate the normal vector of the plane + normal = mathutils.Vector((a, b, c)).normalized() + + # Calculate the point at the center of the plane + point = normal * d + + # Create a new mesh object for the point and line + mesh = bpy.data.meshes.new(name="Plane Center and Normal") + obj = bpy.data.objects.new(name="Plane Object", object_data=mesh) + + # Create the vertices for the point and line + vertices = [ + point, + point + normal + ] + + # Create the edges for the line + edges = [ + (0, 1) + ] + + # Create the mesh data for the point and line + mesh.from_pydata(vertices, edges, []) + + # Add the object to the scene + bpy.context.scene.collection.objects.link(obj) + +draw_plane((0, 1, 0, 11)) \ No newline at end of file diff --git a/addons/cyclops_level_builder/doc/draw_points_in_blender.py b/addons/cyclops_level_builder/doc/draw_points_in_blender.py new file mode 100644 index 0000000..16e5131 --- /dev/null +++ b/addons/cyclops_level_builder/doc/draw_points_in_blender.py @@ -0,0 +1,19 @@ +import bpy +import bmesh + +# Define the list of points for the polygon +points = [(0,0,0), (1,0,0), (1,1,0), (0,1,0)] + +# Create a new mesh and add a new object to the scene +mesh = bpy.data.meshes.new("Polygon") +obj = bpy.data.objects.new("Polygon", mesh) +bpy.context.collection.objects.link(obj) + +# Create a new bmesh and add vertices to it +bm = bmesh.new() +for point in points: + bm.verts.new(point) + +# Add the vertices to the mesh +bm.to_mesh(mesh) +bm.free() \ No newline at end of file diff --git a/addons/cyclops_level_builder/doc/make_polygons.py b/addons/cyclops_level_builder/doc/make_polygons.py new file mode 100644 index 0000000..6b6f1d9 --- /dev/null +++ b/addons/cyclops_level_builder/doc/make_polygons.py @@ -0,0 +1,36 @@ +import bpy +import bmesh + +# Define the list of faces, where each sublist represents a face +#faces = [ +# [(0,0,0), (1,0,0), (1,1,0), (0,1,0)], +# [(1,0,0), (2,0,0), (2,1,0), (1,1,0)] +#] +faces = [ + [(-2.999999, 6, -0.999997), (-2.999999, 9.999996, -0.999997), (-2.999999, 9.999996, 2.999999), (-2.999999, 6, 2.999999)], + [(-2.999999, 9.999996, -0.999997), (-2.999999, 6, -0.999997), (0.999997, 6, -0.999997), (0.999997, 9.999996, -0.999997)], + [(-2.999999, 6, -0.999997), (-2.999999, 6, 2.999999), (-0.999997, 6, 5), (2.999998, 6, 1.000004), (0.999997, 6, -0.999997)], + [(-2.999999, 9.999996, -0.999997), (0.999997, 9.999996, -0.999997), (1.999999, 9.999996, 0.000005), (-1.999997, 9.999996, 4), (-2.999999, 9.999996, 2.999999)], + [(-0.999997, 6, 5), (-2.999999, 6, 2.999999), (-2.999999, 9.999996, 2.999999), (-1.999997, 9.999996, 4), (-0.999997, 7.999996, 5)], + [(0.999997, 9.999996, -0.999997), (0.999997, 6, -0.999997), (2.999999, 6, 1.000004), (2.999999, 7.999996, 1.000004), (1.999998, 9.999996, 0.000004)], + [(-1.999997, 9.999996, 4), (1.999999, 9.999996, 0.000005), (2.999998, 7.999997, 1.000004), (-0.999997, 7.999997, 5)] + +] + + +# Create a new mesh and add a new object to the scene +mesh = bpy.data.meshes.new("Polygon") +obj = bpy.data.objects.new("Polygon", mesh) +bpy.context.collection.objects.link(obj) + +# Create a new bmesh and add vertices and faces to it +bm = bmesh.new() +for face_verts in faces: + # Add vertices for the face + verts = [bm.verts.new(v) for v in face_verts] + # Add a new face between the vertices + bm.faces.new(verts) + +# Update the mesh and free the bmesh +bm.to_mesh(mesh) +bm.free() diff --git a/addons/cyclops_level_builder/docks/material_palette/commands/cmd_mat_dock_add_materials.gd b/addons/cyclops_level_builder/docks/material_palette/commands/cmd_mat_dock_add_materials.gd new file mode 100644 index 0000000..513cb10 --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/commands/cmd_mat_dock_add_materials.gd @@ -0,0 +1,56 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandMaterialDockAddMaterials +extends CyclopsCommand + +#Public +var res_path_list:Array[String] + +#Private +var old_res_path_list:Array[String] + + +func _init(): + command_name = "Add materials" + +func do_it(): +# print("Add Materials do_it") + var mat_dock:MaterialPaletteViewport = builder.material_dock + old_res_path_list = mat_dock.material_list.duplicate() + +# print("old mat list %s" % str(old_res_path_list)) + + var new_list:Array[String] = old_res_path_list.duplicate() + for mat in res_path_list: + if !new_list.has(mat): + new_list.append(mat) + +# print("new mat list %s" % str(new_list)) + + mat_dock.set_materials(new_list) + +func undo_it(): + var mat_dock:MaterialPaletteViewport = builder.material_dock + mat_dock.set_materials(old_res_path_list) diff --git a/addons/cyclops_level_builder/docks/material_palette/commands/cmd_mat_dock_remove_materials.gd b/addons/cyclops_level_builder/docks/material_palette/commands/cmd_mat_dock_remove_materials.gd new file mode 100644 index 0000000..771906c --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/commands/cmd_mat_dock_remove_materials.gd @@ -0,0 +1,52 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name CommandMaterialDockRemoveMaterials +extends CyclopsCommand + +#Public +var res_path_list:Array[String] + +#Private +var old_res_path_list:Array[String] + + +func _init(): + command_name = "Remove materials" + +func do_it(): +# print("Remove Materials do_it") + + var mat_dock:MaterialPaletteViewport = builder.material_dock + old_res_path_list = mat_dock.material_list.duplicate() + + var new_list:Array[String] = old_res_path_list.duplicate() + for mat in res_path_list: + var idx:int = new_list.find(mat) + new_list.remove_at(idx) + mat_dock.set_materials(new_list) + +func undo_it(): + var mat_dock:MaterialPaletteViewport = builder.material_dock + mat_dock.set_materials(old_res_path_list) diff --git a/addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.gd b/addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.gd new file mode 100644 index 0000000..f82a6d3 --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.gd @@ -0,0 +1,191 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Control +class_name MaterialPaletteViewport + +@export var material_list:Array[String] = [] + +@export var thumbnail_group:ThumbnailGroup + +var builder:CyclopsLevelBuilder +#var undo_manager:UndoRedo + +var has_mouse_focus:bool = false + +# Called when the node enters the scene tree for the first time. +func _ready(): +# print("MaterialPaletteViewport") + #undo_manager = UndoRedo.new() + + update_thumbnails() + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass + +func _can_drop_data(at_position:Vector2, data:Variant): +# print("_can_drop_data %s" % data) + return typeof(data) == TYPE_DICTIONARY and data.has("type") and data["type"] == "files" + +func _unhandled_input(event): + if !has_mouse_focus: + return + + if event is InputEventKey: + #print("key event %s" % str(event)) + var e:InputEventKey = event +# if e.keycode == KEY_DELETE: + if e.keycode == KEY_X: + if e.pressed: +# print("mat pal X") + remove_selected_material() + + accept_event() + +func remove_selected_material(): + var cmd:CommandMaterialDockRemoveMaterials = CommandMaterialDockRemoveMaterials.new() + cmd.builder = builder + + for child in $VBoxContainer/ScrollContainer/HFlowContainer.get_children(): + if child.selected: + cmd.res_path_list.append(child.material_path) + + var undo_manager:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo_manager) + +func set_materials(res_path_list:Array[String]): + material_list = res_path_list +# print("set mat list %s" % str(material_list)) + update_thumbnails() + + +func save_state(state:Dictionary): + var substate:Dictionary = {} + state["material_palette"] = substate + + substate["materials"] = material_list.duplicate() + +func load_state(state:Dictionary): + if state == null || !state.has("material_palette"): + return + + var substate:Dictionary = state["material_palette"] + +# print("load_state()") + material_list = [] + if substate.has("materials"): + for mat_path in substate["materials"]: + if ResourceLoader.exists(mat_path): + material_list.append(mat_path) + + update_thumbnails() + +func _drop_data(at_position, data): + var files = data["files"] + #print("--drop") + var add_list:Array[String] + for f in files: +# print("Dropping %s" % f) + var res:Resource = load(f) + if res is Material: + if !material_list.has(f): + add_list.append(f) + + + var cmd:CommandMaterialDockAddMaterials = CommandMaterialDockAddMaterials.new() + cmd.builder = builder + + cmd.res_path_list = add_list + + var undo_manager:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo_manager) + + #print("drop data clear") + #material_list.clear() + +func update_thumbnails(): +# print("update_thumbnails()") + var cur_sel:String + + for child in $VBoxContainer/ScrollContainer/HFlowContainer.get_children(): + if child.selected: + cur_sel = child.material_path + break + + for child in $VBoxContainer/ScrollContainer/HFlowContainer.get_children(): + #print("removing %s" % child.get_class()) + child.group = null + $VBoxContainer/ScrollContainer/HFlowContainer.remove_child(child) + child.queue_free() + + for path in material_list: + var res:Resource = preload("res://addons/cyclops_level_builder/docks/material_palette/material_thumbnail.tscn") + var thumbnail:MaterialThumbnail = res.instantiate() + thumbnail.builder = builder + thumbnail.material_path = path + thumbnail.group = thumbnail_group +# print("adding mat %s" % path) + + + $VBoxContainer/ScrollContainer/HFlowContainer.add_child(thumbnail) + thumbnail.owner = self + + if cur_sel: + for child in $VBoxContainer/ScrollContainer/HFlowContainer.get_children(): + if child.material_path == cur_sel: + child.selected = true + break + + +func _on_visibility_changed(): + #Control freezes for some reason when hidden and then shown, so just regenereate it + if visible: + update_thumbnails() + + + +func _on_remove_all_materials_pressed(): + var cmd:CommandMaterialDockRemoveMaterials = CommandMaterialDockRemoveMaterials.new() + cmd.builder = builder + + cmd.res_path_list = material_list.duplicate() + + var undo_manager:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo_manager) + + + +func _on_remove_sel_pressed(): + remove_selected_material() + + +func _on_h_flow_container_mouse_entered(): + has_mouse_focus = true +# print("_on_h_flow_container_mouse_entered()") + + +func _on_h_flow_container_mouse_exited(): + has_mouse_focus = false +# print("_on_h_flow_container_mouse_exited()") diff --git a/addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.tscn b/addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.tscn new file mode 100644 index 0000000..c5f0584 --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.tscn @@ -0,0 +1,60 @@ +[gd_scene load_steps=4 format=3 uid="uid://o1efx0qxc4n3"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.gd" id="1_xyxg3"] +[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/material_palette/thumbnail_group.gd" id="2_sg6yo"] + +[sub_resource type="Resource" id="Resource_ljbow"] +script = ExtResource("2_sg6yo") + +[node name="Materials" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_xyxg3") +thumbnail_group = SubResource("Resource_ljbow") +metadata/_edit_lock_ = true + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +metadata/_edit_lock_ = true + +[node name="PanelContainer" type="PanelContainer" parent="VBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 0 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/PanelContainer"] +layout_mode = 2 + +[node name="remove_all_materials" type="Button" parent="VBoxContainer/PanelContainer/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 0 +text = "Remove All" + +[node name="remove_sel" type="Button" parent="VBoxContainer/PanelContainer/HBoxContainer"] +layout_mode = 2 +tooltip_text = "Press X to removeselected material." +text = "Remove Selected" + +[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +metadata/_edit_lock_ = true + +[node name="HFlowContainer" type="HFlowContainer" parent="VBoxContainer/ScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"] +[connection signal="pressed" from="VBoxContainer/PanelContainer/HBoxContainer/remove_all_materials" to="." method="_on_remove_all_materials_pressed"] +[connection signal="pressed" from="VBoxContainer/PanelContainer/HBoxContainer/remove_sel" to="." method="_on_remove_sel_pressed"] +[connection signal="mouse_entered" from="VBoxContainer/ScrollContainer/HFlowContainer" to="." method="_on_h_flow_container_mouse_entered"] +[connection signal="mouse_exited" from="VBoxContainer/ScrollContainer/HFlowContainer" to="." method="_on_h_flow_container_mouse_exited"] diff --git a/addons/cyclops_level_builder/docks/material_palette/material_snapshot.gd b/addons/cyclops_level_builder/docks/material_palette/material_snapshot.gd new file mode 100644 index 0000000..df01ad9 --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/material_snapshot.gd @@ -0,0 +1,52 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +@tool +extends SubViewport +class_name MaterialShapshot + +@export var target_material:Material: + get: + return target_material + set(value): + target_material = value + $Node3D/MeshInstance3D.material_override = target_material + +func take_snapshot()->ImageTexture: + #print ("pre-grabbing image %s" % target_material.resource_path) + await RenderingServer.frame_post_draw + #print ("grabbing image %s" % target_material.resource_path) + var image:Image = get_viewport().get_texture().get_image() + var tex:ImageTexture = ImageTexture.create_from_image(image) + return tex + + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass diff --git a/addons/cyclops_level_builder/docks/material_palette/material_snapshot.tscn b/addons/cyclops_level_builder/docks/material_palette/material_snapshot.tscn new file mode 100644 index 0000000..fc4d0cd --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/material_snapshot.tscn @@ -0,0 +1,30 @@ +[gd_scene load_steps=5 format=3] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/material_palette/material_snapshot.gd" id="1_c0jsn"] +[ext_resource type="Material" uid="uid://rdhrhgrb78ls" path="res://addons/cyclops_level_builder/materials/grid.tres" id="2_q7d7x"] + +[sub_resource type="QuadMesh" id="QuadMesh_o8jeg"] + +[sub_resource type="Environment" id="Environment_p06d0"] + +[node name="SubViewport" type="SubViewport"] +own_world_3d = true +size = Vector2i(64, 64) +render_target_update_mode = 4 +script = ExtResource("1_c0jsn") + +[node name="Node3D" type="Node3D" parent="."] + +[node name="Camera3D" type="Camera3D" parent="Node3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1) +projection = 1 + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Node3D"] +mesh = SubResource("QuadMesh_o8jeg") +surface_material_override/0 = ExtResource("2_q7d7x") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Node3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 4) + +[node name="WorldEnvironment" type="WorldEnvironment" parent="Node3D"] +environment = SubResource("Environment_p06d0") diff --git a/addons/cyclops_level_builder/docks/material_palette/material_thumbnail.gd b/addons/cyclops_level_builder/docks/material_palette/material_thumbnail.gd new file mode 100644 index 0000000..688dd89 --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/material_thumbnail.gd @@ -0,0 +1,166 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Control +class_name MaterialThumbnail + +@export var selected:bool = false + +@export_file("*.tres") var material_path:String: + get: + return material_path + set(value): + if material_path == value: + return + + material_path = value + + if ResourceLoader.exists(material_path): + var res:Resource = load(material_path) + #print("loaded res %s" % res) + + if res is Material: + tracked_material = res + else: + tracked_material = null + else: + tracked_material = null + + material_thumbnail_dirty = true + +@export var group:ThumbnailGroup: + get: + return group + set(value): + if group == value: + return + + if group != null: + group.remove_thumbnail(self) + + group = value + + if group != null: + group.add_thumbnail(self) + + +@export var theme_normal:Theme +@export var theme_selected:Theme + +var builder:CyclopsLevelBuilder + +var tracked_material:Material +var material_thumbnail_dirty:bool = true + +var snapper:MaterialShapshot + +# Called when the node enters the scene tree for the first time. +func _ready(): + snapper = preload("res://addons/cyclops_level_builder/docks/material_palette/material_snapshot.tscn").instantiate() + add_child(snapper) + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + if selected: + theme = theme_selected + else: + theme = theme_normal + + if material_thumbnail_dirty: + material_thumbnail_dirty = false + + snapper.target_material = tracked_material + + var tex:ImageTexture = await snapper.take_snapshot() + $VBoxContainer/TextureRect.texture = tex + + if tracked_material: + var name:String = tracked_material.resource_name + if name.is_empty(): + name = material_path.get_file() + var idx:int = name.rfind(".") + if idx != -1: + name = name.substr(0, idx) + $VBoxContainer/MaterialName.text = name + else: + $VBoxContainer/MaterialName.text = "" + + +func _gui_input(event:InputEvent): + if event is InputEventMouseButton: + var e:InputEventMouseButton = event + if e.pressed: + if e.double_click: + apply_material_to_selected() + else: + + if group: + group.select_thumbnail(self) + else: + selected = true + + builder.tool_material_path = material_path + + get_viewport().set_input_as_handled() + + +func apply_material_to_selected(): + var cmd:CommandSetMaterial = CommandSetMaterial.new() + cmd.builder = builder + cmd.material_path = material_path + + var is_obj_mode:bool = builder.mode == CyclopsLevelBuilder.Mode.OBJECT + + var root_blocks:CyclopsBlocks = builder.active_node + for child in root_blocks.get_children(): +# print("child block %s %s" % [child.name, child.get_class()]) +# if child.has_method("append_mesh_wire"): + if child is CyclopsConvexBlock: + #if !(child is MeshInstance3D): +# print("setting child block %s" % child.name) + if child.selected: + if is_obj_mode: + cmd.add_target(child.get_path(), child.control_mesh.get_face_indices()) + else: + var face_indices:PackedInt32Array = child.control_mesh.get_face_indices(true) + if !face_indices.is_empty(): + cmd.add_target(child.get_path(), face_indices) + + if cmd.will_change_anything(): + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo) + + +func _on_focus_entered(): + pass # Replace with function body. + + +func _on_focus_exited(): + pass # Replace with function body. + + +func _on_tree_exiting(): + if group != null: + group.remove_thumbnail(self) diff --git a/addons/cyclops_level_builder/docks/material_palette/material_thumbnail.tscn b/addons/cyclops_level_builder/docks/material_palette/material_thumbnail.tscn new file mode 100644 index 0000000..1c67f92 --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/material_thumbnail.tscn @@ -0,0 +1,43 @@ +[gd_scene load_steps=6 format=3] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/material_palette/material_thumbnail.gd" id="1_bk6mq"] +[ext_resource type="Theme" uid="uid://c0gpl22e2g6ay" path="res://addons/cyclops_level_builder/docks/material_palette/thumbnail_selected_theme.tres" id="1_pvt6l"] +[ext_resource type="Theme" uid="uid://bx26luxdhj3jq" path="res://addons/cyclops_level_builder/docks/material_palette/thumbnail_normal_theme.tres" id="3_a3d05"] + +[sub_resource type="Image" id="Image_s62qo"] +data = { +"data": PackedByteArray(173, 164, 110, 255, 173, 164, 110, 255, 164, 156, 103, 255, 173, 164, 110, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 140, 140, 87, 255, 98, 103, 66, 255, 110, 103, 77, 255, 143, 140, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 168, 162, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 158, 98, 255, 156, 152, 98, 255, 147, 146, 98, 255, 114, 108, 76, 255, 98, 91, 66, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 106, 107, 73, 255, 87, 91, 66, 255, 128, 123, 80, 255, 147, 140, 87, 255, 159, 158, 98, 255, 164, 159, 103, 255, 164, 159, 103, 255, 164, 159, 103, 255, 159, 164, 110, 255, 159, 164, 110, 255, 159, 164, 110, 255, 123, 115, 77, 255, 110, 103, 77, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 173, 164, 110, 255, 173, 164, 110, 255, 159, 152, 99, 255, 173, 164, 110, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 98, 255, 140, 140, 87, 255, 98, 103, 66, 255, 110, 103, 77, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 168, 162, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 158, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 114, 108, 76, 255, 98, 91, 66, 255, 114, 108, 76, 255, 114, 108, 76, 255, 117, 116, 76, 255, 117, 116, 76, 255, 117, 116, 76, 255, 117, 116, 76, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 117, 113, 76, 255, 98, 91, 66, 255, 117, 113, 76, 255, 139, 135, 87, 255, 159, 158, 98, 255, 152, 146, 98, 255, 152, 146, 98, 255, 130, 126, 87, 255, 130, 126, 87, 255, 106, 107, 73, 255, 87, 91, 66, 255, 128, 123, 80, 255, 147, 140, 87, 255, 159, 158, 98, 255, 164, 159, 103, 255, 164, 159, 103, 255, 164, 159, 103, 255, 159, 164, 110, 255, 159, 164, 110, 255, 159, 164, 110, 255, 123, 114, 77, 255, 110, 103, 77, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 173, 164, 110, 255, 159, 152, 99, 255, 168, 159, 106, 255, 173, 164, 110, 255, 173, 164, 99, 255, 168, 162, 99, 255, 168, 162, 99, 255, 159, 158, 99, 255, 159, 158, 98, 255, 159, 158, 98, 255, 140, 140, 87, 255, 98, 103, 66, 255, 110, 103, 77, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 158, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 114, 108, 76, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 110, 108, 77, 255, 110, 108, 77, 255, 110, 108, 77, 255, 110, 108, 77, 255, 87, 91, 66, 255, 87, 91, 66, 255, 147, 140, 87, 255, 147, 140, 87, 255, 159, 158, 98, 255, 164, 159, 103, 255, 164, 159, 103, 255, 164, 159, 103, 255, 159, 164, 110, 255, 159, 164, 110, 255, 159, 164, 110, 255, 123, 114, 77, 255, 110, 103, 77, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 173, 164, 110, 255, 159, 152, 99, 255, 173, 164, 110, 255, 168, 159, 106, 255, 168, 162, 99, 255, 168, 162, 99, 255, 168, 162, 99, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 140, 140, 87, 255, 98, 103, 66, 255, 110, 103, 77, 255, 143, 139, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 158, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 114, 108, 75, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 117, 116, 75, 255, 117, 116, 75, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 135, 87, 255, 139, 135, 87, 255, 98, 91, 66, 255, 117, 113, 75, 255, 139, 135, 87, 255, 139, 135, 87, 255, 139, 135, 87, 255, 159, 158, 98, 255, 152, 145, 98, 255, 152, 145, 98, 255, 152, 145, 98, 255, 173, 164, 110, 255, 128, 123, 79, 255, 87, 91, 66, 255, 147, 139, 87, 255, 147, 140, 87, 255, 159, 158, 98, 255, 173, 164, 110, 255, 164, 159, 103, 255, 164, 159, 103, 255, 159, 164, 110, 255, 159, 164, 110, 255, 159, 164, 110, 255, 123, 114, 77, 255, 126, 120, 83, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 113, 76, 255, 87, 91, 66, 255, 135, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 168, 162, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 163, 162, 102, 255, 156, 153, 94, 255, 147, 145, 87, 255, 147, 145, 87, 255, 110, 102, 77, 255, 126, 120, 83, 255, 159, 158, 98, 255, 159, 158, 98, 255, 185, 176, 123, 255, 176, 170, 114, 255, 168, 163, 107, 255, 168, 163, 107, 255, 163, 159, 102, 255, 173, 163, 110, 255, 159, 158, 98, 255, 168, 162, 105, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 117, 116, 75, 255, 159, 158, 98, 255, 159, 158, 98, 255, 152, 150, 94, 255, 152, 150, 94, 255, 155, 152, 94, 255, 155, 152, 94, 255, 152, 145, 91, 255, 155, 152, 94, 255, 105, 104, 76, 255, 87, 86, 66, 255, 128, 126, 87, 255, 147, 146, 98, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 122, 114, 80, 255, 140, 135, 87, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 149, 141, 94, 255, 149, 141, 94, 255, 149, 141, 94, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 113, 76, 255, 87, 91, 66, 255, 135, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 168, 162, 98, 255, 163, 159, 98, 255, 173, 163, 98, 255, 163, 162, 102, 255, 156, 153, 94, 255, 147, 145, 87, 255, 147, 145, 87, 255, 110, 102, 77, 255, 126, 120, 83, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 168, 163, 107, 255, 168, 163, 107, 255, 168, 163, 107, 255, 163, 159, 102, 255, 163, 159, 102, 255, 163, 159, 102, 255, 163, 159, 102, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 98, 97, 66, 255, 159, 158, 98, 255, 151, 150, 94, 255, 135, 133, 87, 255, 142, 141, 91, 255, 159, 158, 98, 255, 155, 152, 94, 255, 152, 145, 91, 255, 152, 145, 91, 255, 105, 104, 76, 255, 87, 86, 66, 255, 128, 126, 87, 255, 147, 146, 98, 255, 173, 170, 110, 255, 149, 146, 94, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 122, 114, 80, 255, 117, 113, 76, 255, 140, 135, 87, 255, 140, 135, 88, 255, 159, 158, 99, 255, 99, 97, 67, 255, 99, 97, 67, 255, 122, 119, 80, 255, 122, 119, 80, 255, 149, 141, 94, 255, 122, 119, 80, 255, 122, 119, 80, 255, 122, 119, 80, 255, 117, 113, 76, 255, 117, 113, 76, 255, 117, 113, 76, 255, 98, 91, 66, 255, 87, 91, 66, 255, 135, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 168, 162, 98, 255, 163, 162, 102, 255, 147, 145, 87, 255, 147, 145, 87, 255, 147, 145, 87, 255, 110, 102, 77, 255, 126, 120, 83, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 168, 163, 107, 255, 176, 170, 114, 255, 168, 163, 107, 255, 163, 159, 102, 255, 163, 159, 102, 255, 163, 159, 102, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 98, 97, 66, 255, 151, 150, 94, 255, 135, 133, 87, 255, 142, 141, 91, 255, 151, 150, 94, 255, 159, 158, 98, 255, 155, 152, 94, 255, 152, 145, 91, 255, 152, 145, 91, 255, 105, 104, 75, 255, 87, 86, 66, 255, 128, 126, 87, 255, 147, 145, 98, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 170, 110, 255, 149, 140, 94, 255, 149, 140, 94, 255, 122, 114, 80, 255, 98, 91, 66, 255, 99, 92, 66, 255, 117, 113, 76, 255, 117, 113, 76, 255, 99, 92, 67, 255, 99, 97, 67, 255, 99, 97, 67, 255, 99, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 117, 113, 76, 255, 98, 91, 66, 255, 87, 91, 66, 255, 110, 113, 76, 255, 135, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 170, 110, 255, 156, 153, 94, 255, 147, 145, 87, 255, 147, 145, 87, 255, 110, 102, 77, 255, 126, 120, 83, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 163, 159, 102, 255, 163, 159, 102, 255, 163, 159, 102, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 98, 97, 66, 255, 98, 97, 66, 255, 142, 141, 91, 255, 135, 133, 87, 255, 142, 141, 91, 255, 142, 141, 91, 255, 155, 151, 94, 255, 151, 145, 91, 255, 147, 139, 87, 255, 147, 139, 87, 255, 127, 126, 87, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 99, 92, 66, 255, 99, 92, 67, 255, 99, 92, 67, 255, 147, 140, 87, 255, 147, 140, 87, 255, 147, 140, 87, 255, 152, 146, 91, 255, 155, 152, 94, 255, 155, 152, 94, 255, 152, 146, 91, 255, 147, 139, 87, 255, 147, 146, 91, 255, 147, 146, 91, 255, 135, 133, 83, 255, 123, 122, 77, 255, 87, 91, 66, 255, 105, 108, 75, 255, 127, 127, 87, 255, 147, 145, 98, 255, 147, 142, 91, 255, 147, 142, 91, 255, 147, 142, 91, 255, 147, 142, 91, 255, 147, 139, 87, 255, 147, 139, 87, 255, 147, 139, 87, 255, 147, 139, 87, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 117, 113, 75, 255, 147, 145, 98, 255, 147, 141, 91, 255, 147, 141, 91, 255, 147, 145, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 155, 147, 94, 255, 151, 144, 91, 255, 130, 124, 87, 255, 98, 97, 66, 255, 98, 97, 66, 255, 114, 111, 76, 255, 123, 122, 77, 255, 123, 122, 77, 255, 123, 122, 77, 255, 123, 122, 77, 255, 135, 128, 87, 255, 143, 138, 91, 255, 152, 147, 94, 255, 152, 147, 94, 255, 135, 140, 87, 255, 135, 140, 87, 255, 135, 140, 87, 255, 135, 140, 87, 255, 155, 152, 94, 255, 155, 152, 94, 255, 155, 152, 94, 255, 155, 152, 94, 255, 155, 152, 94, 255, 159, 158, 98, 255, 155, 152, 94, 255, 152, 146, 91, 255, 135, 133, 83, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 133, 83, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 105, 108, 75, 255, 123, 114, 77, 255, 123, 114, 77, 255, 123, 114, 77, 255, 123, 114, 77, 255, 98, 97, 66, 255, 114, 111, 73, 255, 114, 111, 73, 255, 114, 111, 73, 255, 98, 91, 66, 255, 117, 112, 75, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 112, 75, 255, 98, 91, 66, 255, 147, 144, 94, 255, 147, 141, 91, 255, 147, 141, 91, 255, 147, 144, 94, 255, 159, 151, 98, 255, 147, 139, 87, 255, 155, 147, 94, 255, 151, 144, 91, 255, 147, 139, 98, 255, 98, 97, 66, 255, 98, 97, 66, 255, 130, 124, 87, 255, 156, 150, 98, 255, 156, 150, 98, 255, 156, 150, 98, 255, 156, 150, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 152, 152, 94, 255, 152, 152, 94, 255, 152, 152, 94, 255, 159, 158, 98, 255, 159, 158, 98, 255, 155, 152, 94, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 155, 152, 94, 255, 155, 152, 94, 255, 159, 158, 98, 255, 159, 158, 98, 255, 147, 145, 91, 255, 135, 133, 83, 255, 87, 91, 66, 255, 127, 127, 87, 255, 127, 127, 87, 255, 127, 127, 87, 255, 135, 129, 83, 255, 135, 129, 83, 255, 123, 114, 77, 255, 123, 114, 77, 255, 98, 97, 66, 255, 114, 111, 73, 255, 114, 111, 73, 255, 114, 111, 73, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 147, 139, 87, 255, 147, 141, 91, 255, 147, 144, 94, 255, 147, 144, 94, 255, 159, 151, 98, 255, 151, 144, 91, 255, 155, 147, 94, 255, 159, 151, 98, 255, 147, 139, 98, 255, 114, 111, 75, 255, 98, 97, 66, 255, 130, 124, 87, 255, 156, 150, 98, 255, 156, 150, 98, 255, 173, 164, 110, 255, 173, 164, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 133, 83, 255, 87, 91, 66, 255, 127, 127, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 147, 142, 91, 255, 98, 97, 66, 255, 147, 139, 87, 255, 147, 139, 87, 255, 147, 139, 87, 255, 139, 135, 87, 255, 117, 112, 75, 255, 117, 112, 75, 255, 117, 112, 75, 255, 117, 115, 75, 255, 117, 115, 75, 255, 117, 115, 75, 255, 139, 138, 87, 255, 139, 135, 87, 255, 159, 157, 98, 255, 117, 112, 75, 255, 98, 91, 66, 255, 117, 112, 75, 255, 117, 112, 75, 255, 98, 91, 66, 255, 98, 91, 66, 255, 147, 141, 91, 255, 147, 141, 91, 255, 147, 141, 91, 255, 147, 144, 94, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 139, 87, 255, 159, 151, 98, 255, 147, 139, 98, 255, 114, 111, 75, 255, 98, 97, 66, 255, 147, 139, 98, 255, 156, 150, 98, 255, 173, 163, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 152, 152, 94, 255, 159, 158, 98, 255, 159, 158, 98, 255, 168, 158, 103, 255, 168, 158, 103, 255, 168, 158, 103, 255, 168, 158, 103, 255, 164, 159, 98, 255, 164, 159, 98, 255, 159, 158, 98, 255, 164, 159, 98, 255, 160, 156, 103, 255, 173, 163, 110, 255, 160, 156, 102, 255, 135, 139, 87, 255, 98, 97, 66, 255, 117, 116, 75, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 133, 87, 255, 98, 97, 66, 255, 139, 138, 87, 255, 159, 157, 98, 255, 159, 157, 98, 255, 163, 157, 98, 255, 163, 157, 98, 255, 156, 151, 98, 255, 147, 145, 98, 255, 151, 150, 98, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 129, 87, 255, 114, 112, 75, 255, 159, 157, 98, 255, 159, 157, 98, 255, 139, 138, 87, 255, 98, 96, 66, 255, 154, 151, 94, 255, 151, 145, 91, 255, 147, 139, 87, 255, 147, 139, 87, 255, 151, 150, 94, 255, 151, 150, 94, 255, 135, 133, 87, 255, 151, 150, 94, 255, 159, 151, 98, 255, 110, 108, 77, 255, 110, 108, 77, 255, 142, 136, 91, 255, 168, 159, 105, 255, 168, 159, 105, 255, 168, 159, 105, 255, 164, 156, 103, 255, 164, 159, 98, 255, 164, 159, 98, 255, 164, 159, 98, 255, 164, 159, 98, 255, 168, 162, 106, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 168, 158, 103, 255, 168, 158, 103, 255, 159, 152, 98, 255, 168, 158, 103, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 159, 98, 255, 164, 159, 98, 255, 173, 163, 110, 255, 173, 163, 110, 255, 160, 156, 102, 255, 135, 139, 87, 255, 98, 97, 66, 255, 117, 115, 75, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 133, 87, 255, 98, 97, 66, 255, 139, 138, 87, 255, 139, 138, 87, 255, 159, 157, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 147, 145, 98, 255, 151, 150, 98, 255, 159, 157, 98, 255, 151, 150, 98, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 129, 87, 255, 98, 96, 65, 255, 159, 157, 98, 255, 159, 157, 98, 255, 139, 138, 87, 255, 98, 96, 66, 255, 154, 151, 94, 255, 147, 139, 87, 255, 147, 139, 87, 255, 147, 139, 87, 255, 142, 141, 91, 255, 159, 158, 98, 255, 151, 150, 94, 255, 151, 150, 94, 255, 159, 151, 98, 255, 110, 108, 77, 255, 110, 108, 77, 255, 142, 136, 91, 255, 168, 159, 105, 255, 168, 159, 105, 255, 168, 159, 105, 255, 173, 163, 110, 255, 168, 162, 98, 255, 168, 162, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 159, 103, 255, 164, 159, 103, 255, 164, 159, 103, 255, 159, 158, 98, 255, 168, 158, 103, 255, 159, 152, 98, 255, 168, 158, 103, 255, 168, 158, 103, 255, 173, 164, 98, 255, 173, 164, 98, 255, 168, 162, 98, 255, 159, 158, 98, 255, 173, 163, 110, 255, 173, 163, 110, 255, 160, 156, 102, 255, 135, 139, 87, 255, 98, 97, 66, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 133, 87, 255, 159, 157, 98, 255, 135, 133, 87, 255, 98, 96, 66, 255, 139, 138, 87, 255, 159, 157, 98, 255, 159, 157, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 156, 151, 98, 255, 154, 153, 98, 255, 159, 157, 98, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 129, 87, 255, 98, 96, 65, 255, 159, 157, 98, 255, 159, 157, 98, 255, 139, 138, 87, 255, 98, 96, 65, 255, 159, 157, 98, 255, 151, 145, 91, 255, 147, 139, 87, 255, 147, 139, 87, 255, 142, 141, 91, 255, 142, 141, 91, 255, 142, 141, 91, 255, 151, 150, 94, 255, 159, 151, 98, 255, 110, 108, 77, 255, 110, 108, 77, 255, 142, 136, 91, 255, 168, 159, 105, 255, 168, 159, 105, 255, 168, 159, 105, 255, 159, 152, 98, 255, 164, 159, 98, 255, 164, 159, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 159, 103, 255, 164, 159, 103, 255, 164, 159, 103, 255, 164, 159, 103, 255, 176, 164, 106, 255, 185, 170, 110, 255, 168, 158, 103, 255, 168, 158, 103, 255, 164, 159, 98, 255, 164, 159, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 110, 255, 160, 156, 102, 255, 160, 156, 102, 255, 147, 147, 94, 255, 98, 97, 66, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 151, 150, 94, 255, 159, 157, 98, 255, 135, 133, 87, 255, 98, 96, 66, 255, 139, 138, 87, 255, 159, 157, 98, 255, 159, 157, 98, 255, 173, 163, 98, 255, 156, 151, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 129, 87, 255, 98, 96, 65, 255, 159, 157, 98, 255, 159, 157, 98, 255, 139, 138, 87, 255, 98, 96, 65, 255, 159, 157, 98, 255, 151, 145, 91, 255, 147, 139, 87, 255, 147, 139, 87, 255, 142, 141, 91, 255, 142, 141, 91, 255, 142, 141, 91, 255, 142, 141, 91, 255, 159, 151, 98, 255, 110, 108, 76, 255, 110, 108, 77, 255, 142, 136, 91, 255, 168, 159, 105, 255, 168, 159, 105, 255, 168, 159, 105, 255, 163, 156, 102, 255, 159, 158, 98, 255, 164, 159, 98, 255, 168, 162, 98, 255, 173, 164, 98, 255, 168, 162, 105, 255, 173, 164, 110, 255, 164, 159, 103, 255, 164, 159, 103, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 152, 98, 255, 159, 152, 98, 255, 159, 152, 98, 255, 159, 152, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 110, 110, 75, 255, 135, 132, 87, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 135, 129, 87, 255, 98, 102, 65, 255, 139, 139, 87, 255, 159, 157, 98, 255, 159, 157, 98, 255, 163, 156, 98, 255, 159, 151, 98, 255, 168, 159, 98, 255, 168, 159, 98, 255, 163, 157, 98, 255, 163, 157, 98, 255, 156, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 127, 87, 255, 98, 91, 65, 255, 142, 139, 91, 255, 142, 139, 91, 255, 142, 139, 91, 255, 109, 102, 76, 255, 142, 139, 91, 255, 142, 139, 91, 255, 142, 139, 91, 255, 142, 139, 91, 255, 142, 141, 91, 255, 142, 141, 91, 255, 142, 141, 91, 255, 142, 141, 91, 255, 139, 138, 87, 255, 117, 115, 75, 255, 117, 115, 75, 255, 139, 138, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 129, 87, 255, 130, 129, 87, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 135, 135, 87, 255, 135, 135, 87, 255, 135, 135, 87, 255, 110, 113, 76, 255, 110, 107, 76, 255, 135, 129, 87, 255, 135, 129, 87, 255, 135, 129, 87, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 110, 110, 75, 255, 110, 110, 75, 255, 135, 132, 87, 255, 135, 132, 87, 255, 159, 151, 98, 255, 135, 129, 87, 255, 135, 129, 87, 255, 87, 85, 65, 255, 98, 102, 65, 255, 117, 120, 75, 255, 159, 157, 98, 255, 159, 157, 98, 255, 168, 159, 98, 255, 163, 156, 98, 255, 173, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 163, 157, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 127, 87, 255, 98, 91, 65, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 142, 139, 91, 255, 142, 139, 91, 255, 126, 120, 83, 255, 109, 102, 76, 255, 109, 108, 76, 255, 109, 108, 76, 255, 109, 108, 76, 255, 109, 108, 76, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 117, 113, 76, 255, 122, 119, 79, 255, 122, 119, 79, 255, 122, 119, 79, 255, 122, 119, 80, 255, 110, 113, 76, 255, 110, 113, 76, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 85, 65, 255, 87, 85, 65, 255, 98, 102, 65, 255, 117, 120, 75, 255, 159, 157, 98, 255, 159, 157, 98, 255, 163, 156, 98, 255, 163, 156, 98, 255, 168, 159, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 156, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 127, 87, 255, 98, 91, 65, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 108, 76, 255, 109, 108, 76, 255, 126, 124, 83, 255, 142, 141, 91, 255, 139, 138, 87, 255, 139, 138, 87, 255, 117, 115, 75, 255, 117, 115, 75, 255, 114, 113, 75, 255, 114, 113, 75, 255, 114, 113, 75, 255, 98, 97, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 135, 135, 87, 255, 135, 135, 87, 255, 110, 113, 76, 255, 87, 91, 66, 255, 87, 86, 66, 255, 135, 129, 87, 255, 135, 129, 87, 255, 110, 107, 75, 255, 139, 135, 87, 255, 139, 135, 87, 255, 139, 135, 87, 255, 139, 135, 87, 255, 135, 132, 87, 255, 135, 132, 87, 255, 135, 132, 87, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 109, 106, 75, 255, 98, 102, 65, 255, 139, 139, 87, 255, 159, 157, 98, 255, 159, 157, 98, 255, 163, 156, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 156, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 127, 87, 255, 98, 91, 65, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 158, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 114, 113, 75, 255, 98, 91, 66, 255, 117, 113, 75, 255, 139, 135, 87, 255, 139, 135, 87, 255, 149, 141, 94, 255, 149, 141, 94, 255, 149, 141, 94, 255, 149, 141, 94, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 98, 97, 66, 255, 110, 108, 77, 255, 159, 152, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 154, 150, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 123, 114, 76, 255, 98, 102, 76, 255, 139, 139, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 168, 162, 105, 255, 168, 162, 105, 255, 172, 163, 111, 255, 172, 163, 111, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 121, 117, 82, 255, 109, 102, 76, 255, 168, 159, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 156, 153, 102, 255, 147, 145, 98, 255, 147, 145, 98, 255, 156, 153, 102, 255, 173, 163, 109, 255, 168, 159, 105, 255, 163, 156, 102, 255, 168, 159, 105, 255, 159, 157, 98, 255, 154, 153, 98, 255, 154, 153, 98, 255, 159, 158, 98, 255, 173, 163, 110, 255, 160, 153, 102, 255, 173, 163, 110, 255, 135, 133, 87, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 152, 98, 255, 159, 152, 98, 255, 159, 152, 98, 255, 159, 152, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 98, 97, 66, 255, 110, 108, 77, 255, 159, 152, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 123, 114, 76, 255, 98, 102, 76, 255, 139, 139, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 168, 162, 105, 255, 172, 163, 109, 255, 172, 163, 111, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 121, 117, 82, 255, 109, 102, 76, 255, 163, 156, 98, 255, 159, 151, 98, 255, 168, 159, 98, 255, 172, 163, 98, 255, 156, 153, 102, 255, 156, 153, 102, 255, 163, 162, 105, 255, 163, 162, 105, 255, 173, 163, 109, 255, 168, 159, 105, 255, 163, 156, 102, 255, 159, 151, 98, 255, 151, 150, 98, 255, 151, 150, 98, 255, 154, 153, 98, 255, 159, 157, 98, 255, 173, 163, 110, 255, 173, 163, 110, 255, 173, 163, 110, 255, 135, 133, 87, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 164, 158, 102, 255, 164, 158, 103, 255, 164, 158, 103, 255, 159, 152, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 98, 97, 66, 255, 110, 108, 77, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 151, 145, 94, 255, 151, 145, 94, 255, 159, 151, 98, 255, 135, 133, 87, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 123, 114, 76, 255, 98, 102, 76, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 168, 162, 105, 255, 168, 162, 105, 255, 168, 162, 105, 255, 168, 162, 105, 255, 185, 176, 123, 255, 147, 139, 86, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 121, 117, 82, 255, 109, 102, 76, 255, 168, 159, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 156, 153, 102, 255, 163, 162, 105, 255, 172, 169, 109, 255, 172, 169, 109, 255, 173, 163, 109, 255, 168, 159, 105, 255, 163, 156, 102, 255, 168, 159, 105, 255, 159, 157, 98, 255, 151, 150, 98, 255, 154, 153, 98, 255, 159, 157, 98, 255, 173, 163, 110, 255, 147, 144, 94, 255, 173, 163, 110, 255, 147, 144, 94, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 163, 158, 102, 255, 164, 158, 103, 255, 173, 170, 110, 255, 164, 158, 103, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 98, 97, 66, 255, 110, 108, 77, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 154, 150, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 151, 145, 94, 255, 151, 145, 94, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 123, 114, 76, 255, 98, 102, 76, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 168, 162, 105, 255, 168, 162, 105, 255, 168, 162, 105, 255, 168, 162, 105, 255, 172, 163, 111, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 121, 117, 82, 255, 109, 102, 76, 255, 168, 159, 98, 255, 172, 163, 98, 255, 168, 159, 98, 255, 163, 156, 98, 255, 156, 153, 102, 255, 156, 153, 102, 255, 156, 153, 102, 255, 163, 162, 105, 255, 172, 163, 109, 255, 173, 163, 109, 255, 168, 159, 105, 255, 168, 159, 105, 255, 159, 157, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 157, 98, 255, 173, 163, 110, 255, 173, 163, 110, 255, 173, 163, 110, 255, 147, 144, 94, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 163, 158, 102, 255, 164, 158, 103, 255, 164, 158, 103, 255, 164, 158, 103, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 110, 108, 77, 255, 142, 136, 91, 255, 159, 151, 98, 255, 142, 136, 91, 255, 151, 150, 98, 255, 154, 153, 98, 255, 151, 150, 98, 255, 154, 153, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 121, 120, 82, 255, 98, 96, 65, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 159, 151, 98, 255, 159, 151, 109, 255, 159, 151, 109, 255, 126, 118, 86, 255, 109, 102, 76, 255, 156, 153, 102, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 139, 98, 255, 159, 157, 98, 255, 154, 151, 98, 255, 154, 151, 98, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 157, 105, 255, 156, 151, 102, 255, 156, 151, 102, 255, 163, 157, 105, 255, 159, 157, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 133, 87, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 110, 108, 77, 255, 142, 136, 91, 255, 159, 151, 98, 255, 126, 123, 83, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 154, 150, 98, 255, 159, 151, 98, 255, 151, 147, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 121, 120, 82, 255, 98, 96, 65, 255, 139, 138, 87, 255, 159, 157, 98, 255, 159, 157, 98, 255, 156, 151, 98, 255, 156, 151, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 159, 151, 98, 255, 159, 151, 109, 255, 159, 151, 109, 255, 126, 118, 86, 255, 109, 102, 76, 255, 147, 145, 98, 255, 156, 153, 102, 255, 156, 153, 102, 255, 156, 153, 102, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 154, 151, 98, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 147, 139, 87, 255, 147, 145, 98, 255, 156, 151, 102, 255, 156, 151, 102, 255, 163, 157, 105, 255, 159, 157, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 133, 87, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 110, 108, 77, 255, 159, 151, 98, 255, 159, 151, 98, 255, 142, 136, 91, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 154, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 121, 120, 82, 255, 98, 96, 65, 255, 139, 138, 86, 255, 159, 157, 98, 255, 159, 157, 98, 255, 156, 151, 98, 255, 156, 151, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 159, 151, 98, 255, 159, 151, 109, 255, 159, 151, 109, 255, 126, 118, 86, 255, 109, 102, 76, 255, 156, 153, 102, 255, 156, 153, 102, 255, 163, 162, 105, 255, 172, 169, 109, 255, 159, 157, 98, 255, 154, 151, 98, 255, 154, 151, 98, 255, 159, 157, 98, 255, 172, 163, 109, 255, 172, 163, 109, 255, 163, 156, 102, 255, 173, 163, 109, 255, 173, 163, 109, 255, 173, 163, 109, 255, 163, 157, 105, 255, 163, 157, 105, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 158, 98, 255, 135, 133, 87, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 164, 98, 255, 173, 165, 103, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 110, 108, 77, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 158, 98, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 109, 108, 76, 255, 98, 96, 65, 255, 117, 115, 75, 255, 139, 138, 86, 255, 159, 157, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 163, 157, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 163, 156, 98, 255, 159, 151, 109, 255, 159, 151, 109, 255, 109, 102, 76, 255, 109, 102, 76, 255, 156, 153, 102, 255, 156, 153, 102, 255, 156, 153, 102, 255, 156, 153, 102, 255, 154, 151, 98, 255, 154, 151, 98, 255, 154, 151, 98, 255, 154, 151, 98, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 157, 105, 255, 163, 157, 105, 255, 163, 157, 105, 255, 163, 157, 105, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 158, 98, 255, 135, 133, 87, 255, 98, 91, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 170, 110, 255, 173, 164, 98, 255, 173, 168, 105, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 123, 114, 77, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 158, 98, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 139, 87, 255, 147, 139, 87, 255, 151, 144, 91, 255, 151, 144, 91, 255, 139, 138, 87, 255, 159, 157, 98, 255, 159, 157, 98, 255, 98, 96, 65, 255, 98, 91, 65, 255, 114, 108, 75, 255, 130, 127, 86, 255, 130, 127, 86, 255, 139, 135, 86, 255, 139, 135, 86, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 114, 112, 75, 255, 114, 112, 75, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 142, 139, 91, 255, 142, 139, 91, 255, 142, 139, 91, 255, 142, 139, 91, 255, 142, 139, 91, 255, 139, 138, 87, 255, 117, 115, 75, 255, 117, 115, 75, 255, 117, 115, 75, 255, 98, 91, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 123, 114, 77, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 151, 150, 98, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 144, 91, 255, 147, 139, 87, 255, 151, 144, 91, 255, 151, 144, 91, 255, 139, 138, 87, 255, 159, 157, 98, 255, 159, 157, 98, 255, 98, 96, 65, 255, 98, 91, 65, 255, 98, 91, 65, 255, 114, 108, 75, 255, 114, 108, 75, 255, 98, 102, 65, 255, 98, 102, 65, 255, 117, 118, 75, 255, 98, 102, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 130, 128, 86, 255, 114, 112, 75, 255, 98, 96, 65, 255, 139, 131, 86, 255, 139, 131, 86, 255, 139, 131, 86, 255, 139, 131, 86, 255, 139, 138, 86, 255, 139, 138, 86, 255, 139, 138, 86, 255, 117, 115, 75, 255, 126, 120, 82, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 98, 96, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 91, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 135, 126, 83, 255, 159, 151, 98, 255, 147, 139, 91, 255, 159, 151, 98, 255, 151, 150, 98, 255, 151, 150, 98, 255, 151, 150, 98, 255, 151, 150, 98, 255, 151, 144, 91, 255, 147, 139, 87, 255, 151, 144, 91, 255, 151, 144, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 98, 96, 65, 255, 98, 91, 65, 255, 98, 91, 65, 255, 114, 108, 75, 255, 114, 108, 75, 255, 98, 102, 65, 255, 98, 102, 65, 255, 98, 102, 65, 255, 98, 102, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 91, 65, 255, 98, 91, 65, 255, 98, 91, 65, 255, 98, 91, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 139, 138, 86, 255, 142, 139, 91, 255, 142, 139, 91, 255, 126, 120, 82, 255, 126, 120, 83, 255, 126, 120, 83, 255, 142, 139, 91, 255, 142, 139, 91, 255, 142, 139, 91, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 98, 91, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 110, 255, 159, 158, 98, 255, 164, 159, 103, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 135, 126, 83, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 151, 150, 98, 255, 154, 153, 98, 255, 154, 153, 98, 255, 159, 157, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 98, 96, 65, 255, 98, 91, 65, 255, 130, 127, 86, 255, 147, 145, 98, 255, 147, 145, 98, 255, 139, 135, 86, 255, 139, 135, 86, 255, 117, 118, 75, 255, 117, 118, 75, 255, 117, 114, 75, 255, 117, 114, 75, 255, 139, 133, 86, 255, 139, 133, 86, 255, 130, 128, 86, 255, 130, 128, 86, 255, 130, 128, 86, 255, 114, 112, 75, 255, 117, 109, 75, 255, 117, 109, 75, 255, 117, 109, 75, 255, 98, 91, 65, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 164, 159, 103, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 87, 91, 66, 255, 130, 127, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 98, 96, 65, 255, 98, 96, 65, 255, 130, 129, 86, 255, 147, 145, 98, 255, 147, 145, 98, 255, 142, 141, 93, 255, 139, 138, 91, 255, 139, 138, 91, 255, 142, 141, 93, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 142, 141, 93, 255, 139, 138, 91, 255, 139, 138, 91, 255, 142, 141, 93, 255, 134, 133, 86, 255, 147, 139, 98, 255, 134, 128, 91, 255, 109, 108, 76, 255, 135, 128, 91, 255, 147, 145, 98, 255, 151, 150, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 153, 98, 255, 159, 156, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 87, 91, 66, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 139, 133, 87, 255, 139, 133, 87, 255, 139, 133, 87, 255, 139, 133, 87, 255, 159, 151, 98, 255, 117, 114, 75, 255, 98, 96, 65, 255, 130, 129, 86, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 134, 133, 86, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 142, 141, 93, 255, 134, 133, 86, 255, 142, 141, 93, 255, 147, 145, 98, 255, 142, 141, 93, 255, 147, 139, 98, 255, 147, 139, 98, 255, 109, 108, 76, 255, 135, 128, 91, 255, 147, 145, 98, 255, 154, 153, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 151, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 135, 133, 87, 255, 159, 158, 98, 255, 98, 97, 66, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 135, 87, 255, 87, 91, 66, 255, 98, 91, 66, 255, 114, 108, 75, 255, 98, 91, 66, 255, 114, 108, 75, 255, 117, 114, 75, 255, 117, 114, 75, 255, 98, 97, 66, 255, 98, 96, 66, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 130, 129, 86, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 142, 141, 93, 255, 147, 145, 98, 255, 139, 138, 91, 255, 147, 145, 98, 255, 139, 138, 91, 255, 134, 133, 86, 255, 142, 141, 93, 255, 147, 145, 98, 255, 142, 141, 93, 255, 147, 139, 98, 255, 135, 128, 91, 255, 109, 108, 76, 255, 135, 128, 91, 255, 151, 150, 98, 255, 154, 153, 98, 255, 159, 157, 98, 255, 151, 150, 98, 255, 159, 151, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 142, 141, 91, 255, 142, 141, 91, 255, 142, 141, 91, 255, 159, 158, 98, 255, 110, 113, 76, 255, 110, 113, 76, 255, 110, 113, 75, 255, 87, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 117, 114, 75, 255, 117, 114, 75, 255, 139, 133, 87, 255, 139, 133, 87, 255, 117, 114, 75, 255, 117, 114, 75, 255, 117, 114, 75, 255, 117, 114, 75, 255, 117, 114, 75, 255, 98, 96, 65, 255, 98, 96, 65, 255, 114, 112, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 142, 141, 93, 255, 147, 145, 98, 255, 147, 145, 98, 255, 142, 141, 93, 255, 147, 145, 98, 255, 139, 138, 91, 255, 147, 145, 98, 255, 134, 133, 86, 255, 134, 133, 86, 255, 142, 141, 93, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 139, 98, 255, 135, 128, 91, 255, 109, 108, 76, 255, 121, 118, 82, 255, 147, 145, 98, 255, 154, 153, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 158, 98, 255, 135, 133, 87, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 117, 116, 75, 255, 110, 108, 77, 255, 110, 108, 77, 255, 110, 108, 77, 255, 110, 108, 77, 255, 117, 113, 76, 255, 117, 113, 76, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 102, 66, 255, 139, 139, 87, 255, 139, 139, 87, 255, 159, 158, 98, 255, 156, 151, 98, 255, 156, 151, 98, 255, 156, 151, 98, 255, 163, 157, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 156, 150, 98, 255, 156, 150, 98, 255, 156, 150, 98, 255, 123, 121, 76, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 147, 145, 98, 255, 147, 144, 93, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 139, 86, 255, 147, 139, 86, 255, 154, 147, 93, 255, 154, 147, 93, 255, 151, 144, 91, 255, 147, 145, 98, 255, 130, 128, 86, 255, 114, 112, 75, 255, 114, 112, 75, 255, 142, 139, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 142, 139, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 87, 85, 66, 255, 110, 107, 75, 255, 87, 86, 66, 255, 135, 129, 87, 255, 123, 114, 77, 255, 123, 114, 77, 255, 123, 114, 77, 255, 123, 114, 77, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 113, 75, 255, 98, 102, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 163, 157, 98, 255, 173, 163, 98, 255, 163, 157, 102, 255, 163, 157, 102, 255, 163, 157, 102, 255, 163, 157, 102, 255, 173, 163, 109, 255, 173, 163, 109, 255, 156, 150, 98, 255, 139, 135, 87, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 147, 145, 98, 255, 147, 144, 93, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 144, 91, 255, 154, 147, 93, 255, 159, 151, 98, 255, 154, 147, 93, 255, 147, 145, 98, 255, 130, 128, 86, 255, 114, 112, 75, 255, 130, 128, 86, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 110, 110, 75, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 159, 151, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 113, 75, 255, 98, 102, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 147, 145, 98, 255, 173, 163, 98, 255, 168, 163, 105, 255, 163, 157, 102, 255, 163, 157, 102, 255, 163, 157, 102, 255, 173, 163, 109, 255, 173, 163, 109, 255, 156, 150, 98, 255, 139, 135, 87, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 154, 150, 98, 255, 151, 147, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 144, 91, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 114, 112, 75, 255, 98, 96, 65, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 135, 135, 87, 255, 135, 135, 87, 255, 135, 135, 87, 255, 135, 135, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 159, 157, 98, 255, 135, 133, 87, 255, 135, 132, 87, 255, 135, 132, 87, 255, 135, 132, 87, 255, 110, 110, 75, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 159, 151, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 113, 75, 255, 98, 102, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 163, 158, 98, 255, 173, 163, 98, 255, 168, 163, 105, 255, 168, 163, 105, 255, 173, 169, 109, 255, 163, 157, 102, 255, 173, 163, 109, 255, 173, 163, 109, 255, 156, 150, 98, 255, 123, 121, 76, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 151, 147, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 154, 147, 93, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 114, 112, 75, 255, 98, 96, 65, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 87, 91, 65, 255, 87, 91, 65, 255, 87, 91, 65, 255, 87, 91, 65, 255, 87, 85, 65, 255, 87, 85, 65, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 135, 129, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 147, 142, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 126, 120, 83, 255, 123, 114, 77, 255, 173, 163, 110, 255, 173, 163, 110, 255, 156, 147, 98, 255, 173, 163, 98, 255, 159, 151, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 168, 162, 105, 255, 168, 162, 105, 255, 173, 163, 109, 255, 163, 159, 102, 255, 173, 163, 109, 255, 173, 163, 109, 255, 173, 163, 109, 255, 109, 114, 76, 255, 98, 91, 65, 255, 130, 127, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 151, 147, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 154, 150, 98, 255, 154, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 105, 103, 75, 255, 86, 85, 65, 255, 109, 114, 76, 255, 142, 142, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 139, 138, 87, 255, 98, 96, 65, 255, 87, 91, 65, 255, 87, 91, 65, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 135, 133, 87, 255, 173, 163, 98, 255, 173, 164, 98, 255, 156, 156, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 126, 120, 83, 255, 123, 114, 77, 255, 156, 147, 98, 255, 173, 163, 110, 255, 156, 147, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 168, 162, 105, 255, 168, 162, 105, 255, 173, 163, 109, 255, 159, 157, 98, 255, 173, 163, 109, 255, 173, 163, 109, 255, 151, 147, 98, 255, 109, 114, 76, 255, 98, 91, 65, 255, 130, 127, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 154, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 147, 98, 255, 154, 150, 98, 255, 151, 147, 98, 255, 147, 145, 98, 255, 151, 147, 98, 255, 154, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 105, 103, 75, 255, 87, 85, 65, 255, 126, 129, 82, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 98, 96, 65, 255, 87, 91, 65, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 86, 66, 255, 110, 108, 75, 255, 87, 86, 66, 255, 135, 133, 87, 255, 173, 163, 98, 255, 164, 159, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 110, 102, 77, 255, 123, 114, 77, 255, 156, 147, 98, 255, 173, 163, 110, 255, 156, 147, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 168, 162, 105, 255, 168, 162, 105, 255, 163, 159, 102, 255, 168, 162, 105, 255, 173, 163, 109, 255, 173, 163, 109, 255, 173, 163, 109, 255, 109, 114, 76, 255, 98, 91, 65, 255, 130, 127, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 154, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 154, 150, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 127, 126, 87, 255, 87, 85, 65, 255, 142, 142, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 142, 142, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 98, 96, 65, 255, 87, 91, 65, 255, 135, 132, 87, 255, 135, 132, 87, 255, 135, 132, 87, 255, 135, 132, 87, 255, 135, 132, 87, 255, 135, 132, 87, 255, 159, 151, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 87, 86, 66, 255, 135, 133, 87, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 110, 103, 77, 255, 123, 114, 77, 255, 156, 147, 98, 255, 173, 163, 110, 255, 173, 163, 110, 255, 173, 163, 98, 255, 168, 159, 98, 255, 168, 159, 98, 255, 173, 163, 98, 255, 163, 159, 102, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 173, 163, 109, 255, 173, 163, 109, 255, 173, 163, 109, 255, 109, 114, 76, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 154, 150, 98, 255, 159, 151, 98, 255, 154, 150, 98, 255, 154, 150, 98, 255, 154, 150, 98, 255, 154, 150, 98, 255, 151, 147, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 127, 126, 87, 255, 87, 85, 65, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 139, 138, 87, 255, 98, 96, 65, 255, 87, 91, 66, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 87, 86, 66, 255, 110, 108, 75, 255, 173, 164, 98, 255, 147, 152, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 123, 114, 77, 255, 147, 142, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 168, 162, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 109, 108, 76, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 150, 102, 255, 142, 141, 94, 255, 159, 157, 109, 255, 135, 133, 87, 255, 151, 144, 91, 255, 151, 144, 91, 255, 154, 147, 93, 255, 154, 147, 93, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 127, 127, 87, 255, 87, 91, 65, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 147, 145, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 142, 141, 91, 255, 109, 108, 76, 255, 98, 91, 66, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 158, 98, 255, 168, 162, 98, 255, 168, 162, 98, 255, 168, 162, 98, 255, 163, 159, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 98, 91, 66, 255, 168, 162, 98, 255, 159, 158, 98, 255, 168, 162, 98, 255, 168, 162, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 123, 114, 77, 255, 147, 142, 91, 255, 147, 142, 91, 255, 159, 158, 98, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 168, 162, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 109, 108, 76, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 150, 102, 255, 151, 150, 102, 255, 159, 157, 109, 255, 135, 133, 87, 255, 154, 147, 93, 255, 154, 147, 93, 255, 154, 147, 93, 255, 154, 147, 93, 255, 151, 147, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 127, 127, 87, 255, 87, 91, 65, 255, 147, 145, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 147, 145, 91, 255, 159, 157, 98, 255, 142, 141, 91, 255, 126, 124, 83, 255, 109, 108, 76, 255, 98, 91, 66, 255, 159, 157, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 98, 91, 66, 255, 168, 162, 98, 255, 164, 159, 98, 255, 164, 159, 98, 255, 164, 159, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 123, 114, 77, 255, 147, 142, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 163, 156, 102, 255, 159, 151, 98, 255, 163, 156, 102, 255, 168, 159, 105, 255, 173, 163, 98, 255, 159, 158, 98, 255, 168, 162, 98, 255, 163, 159, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 109, 108, 76, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 150, 102, 255, 151, 150, 102, 255, 151, 150, 102, 255, 151, 150, 102, 255, 154, 147, 94, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 139, 87, 255, 154, 150, 98, 255, 154, 150, 98, 255, 147, 145, 98, 255, 154, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 105, 108, 75, 255, 87, 91, 65, 255, 147, 145, 91, 255, 147, 145, 91, 255, 147, 145, 91, 255, 147, 145, 91, 255, 159, 157, 98, 255, 142, 141, 91, 255, 126, 124, 83, 255, 109, 108, 76, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 113, 75, 255, 98, 91, 66, 255, 173, 164, 98, 255, 173, 164, 98, 255, 168, 162, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 123, 114, 77, 255, 147, 142, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 151, 98, 255, 173, 163, 110, 255, 163, 156, 102, 255, 163, 156, 102, 255, 173, 163, 98, 255, 168, 162, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 109, 108, 76, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 142, 141, 94, 255, 142, 141, 94, 255, 151, 150, 102, 255, 142, 141, 94, 255, 151, 144, 91, 255, 154, 147, 94, 255, 154, 147, 94, 255, 147, 139, 87, 255, 147, 145, 98, 255, 154, 150, 98, 255, 154, 150, 98, 255, 154, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 105, 108, 75, 255, 87, 91, 65, 255, 123, 121, 76, 255, 123, 121, 76, 255, 123, 121, 76, 255, 123, 121, 76, 255, 126, 124, 83, 255, 126, 124, 83, 255, 109, 108, 76, 255, 110, 108, 76, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 168, 162, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 117, 116, 76, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 151, 150, 94, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 151, 150, 94, 255, 159, 158, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 123, 121, 76, 255, 98, 96, 66, 255, 114, 112, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 145, 94, 255, 159, 151, 98, 255, 159, 151, 98, 255, 151, 145, 94, 255, 151, 145, 94, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 142, 139, 94, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 105, 108, 75, 255, 87, 91, 65, 255, 98, 91, 65, 255, 98, 91, 65, 255, 98, 91, 65, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 97, 66, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 163, 159, 98, 255, 173, 163, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 117, 116, 76, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 151, 150, 94, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 157, 98, 255, 123, 121, 76, 255, 98, 96, 66, 255, 114, 112, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 151, 145, 94, 255, 159, 151, 98, 255, 151, 145, 94, 255, 151, 145, 94, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 142, 139, 94, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 105, 108, 75, 255, 87, 91, 65, 255, 114, 108, 75, 255, 114, 108, 75, 255, 114, 108, 75, 255, 114, 108, 75, 255, 117, 110, 75, 255, 139, 132, 87, 255, 139, 132, 87, 255, 117, 110, 75, 255, 98, 97, 66, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 168, 162, 98, 255, 173, 163, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 117, 116, 76, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 151, 150, 94, 255, 151, 150, 94, 255, 151, 150, 94, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 123, 121, 76, 255, 98, 97, 66, 255, 114, 112, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 151, 145, 94, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 142, 139, 94, 255, 142, 139, 94, 255, 142, 139, 94, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 105, 108, 75, 255, 87, 91, 66, 255, 114, 108, 75, 255, 130, 127, 87, 255, 130, 127, 87, 255, 147, 145, 98, 255, 139, 132, 87, 255, 159, 151, 98, 255, 159, 151, 98, 255, 139, 132, 87, 255, 98, 97, 66, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 117, 113, 76, 255, 140, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 116, 76, 255, 117, 116, 76, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 147, 145, 91, 255, 147, 145, 91, 255, 147, 145, 91, 255, 123, 121, 76, 255, 98, 97, 66, 255, 114, 112, 75, 255, 130, 129, 87, 255, 130, 129, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 142, 139, 91, 255, 135, 133, 87, 255, 142, 139, 91, 255, 142, 139, 91, 255, 135, 133, 87, 255, 135, 133, 87, 255, 135, 127, 87, 255, 135, 127, 87, 255, 135, 127, 87, 255, 139, 133, 91, 255, 147, 145, 98, 255, 147, 145, 98, 255, 105, 108, 75, 255, 87, 91, 66, 255, 114, 108, 75, 255, 130, 127, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 98, 97, 66, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 98, 91, 66, 255, 117, 113, 76, 255, 117, 113, 76, 255, 117, 113, 76, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 110, 108, 76, 255, 87, 86, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 117, 113, 75, 255, 98, 91, 66, 255, 114, 108, 75, 255, 114, 108, 75, 255, 114, 108, 75, 255, 114, 108, 75, 255, 117, 114, 75, 255, 117, 114, 75, 255, 117, 114, 75, 255, 98, 97, 66, 255, 87, 85, 66, 255, 105, 102, 73, 255, 87, 85, 66, 255, 105, 102, 73, 255, 105, 102, 73, 255, 127, 121, 79, 255, 127, 121, 79, 255, 127, 121, 79, 255, 105, 108, 75, 255, 105, 108, 75, 255, 105, 108, 75, 255, 105, 108, 75, 255, 114, 108, 75, 255, 114, 108, 75, 255, 114, 108, 75, 255, 114, 108, 75, 255, 105, 107, 73, 255, 105, 107, 73, 255, 87, 91, 66, 255, 87, 91, 66, 255, 110, 108, 76, 255, 130, 126, 87, 255, 151, 145, 98, 255, 173, 163, 110, 255, 159, 163, 98, 255, 159, 163, 98, 255, 154, 156, 94, 255, 147, 139, 87, 255, 110, 102, 77, 255, 126, 120, 83, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 164, 98, 255, 159, 152, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 87, 91, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 117, 116, 76, 255, 117, 116, 76, 255, 117, 116, 76, 255, 98, 97, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 114, 108, 75, 255, 114, 108, 75, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 110, 108, 76, 255, 130, 126, 87, 255, 151, 145, 98, 255, 173, 163, 110, 255, 151, 147, 91, 255, 159, 163, 98, 255, 159, 163, 98, 255, 147, 139, 87, 255, 110, 102, 77, 255, 110, 102, 77, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 168, 159, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 87, 91, 66, 255, 87, 86, 66, 255, 147, 146, 98, 255, 147, 146, 98, 255, 128, 126, 87, 255, 159, 158, 99, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 134, 87, 255, 135, 133, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 98, 91, 66, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 139, 133, 87, 255, 117, 114, 75, 255, 139, 133, 87, 255, 139, 133, 87, 255, 127, 121, 79, 255, 127, 121, 79, 255, 105, 102, 73, 255, 105, 102, 73, 255, 105, 102, 73, 255, 127, 121, 79, 255, 127, 121, 79, 255, 147, 139, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 127, 87, 255, 130, 127, 87, 255, 147, 145, 98, 255, 147, 139, 87, 255, 147, 139, 87, 255, 147, 139, 87, 255, 87, 91, 66, 255, 110, 108, 76, 255, 151, 145, 98, 255, 151, 145, 98, 255, 173, 163, 110, 255, 159, 163, 98, 255, 159, 163, 98, 255, 159, 163, 98, 255, 147, 139, 87, 255, 110, 102, 77, 255, 126, 120, 83, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 87, 91, 66, 255, 106, 104, 76, 255, 147, 146, 98, 255, 147, 146, 98, 255, 147, 146, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 113, 76, 255, 98, 91, 66, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 139, 133, 87, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 139, 87, 255, 147, 139, 87, 255, 147, 139, 87, 255, 147, 139, 87, 255, 105, 102, 73, 255, 127, 121, 79, 255, 147, 139, 87, 255, 147, 139, 87, 255, 127, 127, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 139, 87, 255, 147, 139, 87, 255, 147, 139, 87, 255, 87, 91, 66, 255, 110, 108, 77, 255, 151, 145, 98, 255, 173, 163, 110, 255, 173, 163, 110, 255, 159, 163, 98, 255, 159, 163, 98, 255, 159, 163, 98, 255, 147, 139, 87, 255, 110, 102, 77, 255, 126, 120, 83, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 87, 91, 66, 255, 106, 104, 76, 255, 147, 146, 98, 255, 147, 146, 99, 255, 147, 146, 99, 255, 147, 146, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 98, 255, 164, 162, 106, 255, 164, 162, 106, 255, 164, 162, 106, 255, 164, 162, 106, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 113, 76, 255, 110, 103, 77, 255, 142, 135, 91, 255, 159, 152, 98, 255, 159, 152, 98, 255, 173, 170, 110, 255, 147, 145, 98, 255, 163, 162, 105, 255, 163, 162, 105, 255, 159, 158, 98, 255, 159, 158, 98, 255, 142, 138, 91, 255, 135, 127, 87, 255, 98, 97, 66, 255, 114, 113, 75, 255, 130, 129, 87, 255, 130, 129, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 156, 153, 102, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 153, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 139, 138, 87, 255, 98, 97, 66, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 110, 255, 163, 158, 102, 255, 163, 158, 102, 255, 147, 145, 87, 255, 98, 97, 66, 255, 117, 116, 75, 255, 159, 158, 98, 255, 159, 158, 98, 255, 149, 147, 98, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 170, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 110, 103, 77, 255, 143, 135, 92, 255, 159, 152, 99, 255, 159, 152, 99, 255, 164, 158, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 164, 162, 106, 255, 164, 162, 106, 255, 156, 153, 103, 255, 173, 170, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 110, 103, 77, 255, 142, 135, 91, 255, 159, 152, 98, 255, 159, 152, 98, 255, 173, 170, 110, 255, 147, 145, 98, 255, 163, 162, 105, 255, 163, 162, 105, 255, 159, 158, 98, 255, 159, 158, 98, 255, 142, 138, 91, 255, 135, 127, 87, 255, 98, 97, 66, 255, 114, 113, 75, 255, 130, 129, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 163, 162, 105, 255, 159, 156, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 156, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 98, 97, 66, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 110, 255, 173, 163, 110, 255, 163, 158, 102, 255, 147, 145, 87, 255, 98, 97, 66, 255, 117, 116, 76, 255, 139, 138, 87, 255, 159, 158, 98, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 170, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 110, 103, 77, 255, 159, 152, 99, 255, 159, 152, 99, 255, 159, 152, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 164, 162, 106, 255, 164, 162, 106, 255, 147, 146, 98, 255, 173, 170, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 110, 103, 77, 255, 142, 135, 91, 255, 159, 152, 98, 255, 159, 152, 98, 255, 173, 170, 110, 255, 156, 153, 102, 255, 163, 162, 105, 255, 163, 162, 105, 255, 159, 158, 98, 255, 159, 158, 98, 255, 142, 138, 91, 255, 135, 127, 87, 255, 98, 97, 66, 255, 114, 113, 75, 255, 130, 129, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 156, 153, 102, 255, 156, 153, 102, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 156, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 98, 97, 66, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 156, 152, 94, 255, 163, 158, 102, 255, 164, 158, 102, 255, 147, 145, 87, 255, 98, 97, 66, 255, 98, 97, 66, 255, 139, 138, 87, 255, 139, 138, 87, 255, 173, 170, 110, 255, 173, 170, 110, 255, 149, 147, 98, 255, 173, 170, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 99, 97, 66, 255, 110, 103, 77, 255, 159, 152, 99, 255, 159, 152, 99, 255, 159, 152, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 164, 162, 106, 255, 164, 162, 106, 255, 156, 153, 103, 255, 164, 162, 106, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 110, 103, 77, 255, 142, 135, 91, 255, 159, 152, 98, 255, 159, 152, 98, 255, 164, 162, 105, 255, 164, 162, 105, 255, 164, 162, 105, 255, 156, 153, 102, 255, 159, 158, 98, 255, 159, 158, 98, 255, 142, 138, 91, 255, 142, 138, 91, 255, 98, 97, 66, 255, 114, 113, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 173, 170, 110, 255, 156, 153, 102, 255, 156, 153, 102, 255, 159, 156, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 156, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 98, 97, 66, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 156, 152, 94, 255, 164, 158, 103, 255, 156, 152, 94, 255, 147, 145, 87, 255, 98, 97, 66, 255, 98, 97, 66, 255, 117, 116, 76, 255, 117, 116, 76, 255, 98, 103, 77, 255, 98, 103, 77, 255, 98, 103, 77, 255, 98, 103, 77, 255, 98, 97, 66, 255, 98, 97, 66, 255, 99, 97, 66, 255, 99, 97, 67, 255, 110, 103, 77, 255, 159, 152, 99, 255, 159, 152, 99, 255, 159, 152, 99, 255, 164, 159, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 164, 162, 106, 255, 164, 162, 106, 255, 164, 162, 106, 255, 156, 153, 103, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 110, 108, 77, 255, 143, 141, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 110, 255, 173, 164, 110, 255, 163, 156, 105, 255, 147, 139, 98, 255, 98, 97, 66, 255, 114, 113, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 152, 98, 255, 185, 176, 123, 255, 159, 152, 98, 255, 159, 152, 98, 255, 159, 158, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 142, 141, 91, 255, 110, 108, 77, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 168, 159, 98, 255, 164, 156, 98, 255, 159, 152, 98, 255, 114, 107, 73, 255, 98, 91, 66, 255, 98, 91, 66, 255, 114, 107, 73, 255, 123, 128, 87, 255, 123, 128, 87, 255, 123, 128, 87, 255, 140, 140, 91, 255, 159, 158, 98, 255, 159, 158, 99, 255, 159, 158, 99, 255, 99, 103, 67, 255, 110, 103, 77, 255, 159, 152, 99, 255, 159, 152, 99, 255, 159, 152, 99, 255, 168, 162, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 170, 110, 255, 164, 162, 106, 255, 164, 162, 106, 255, 164, 162, 106, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 110, 108, 77, 255, 143, 141, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 156, 147, 103, 255, 98, 97, 66, 255, 114, 113, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 152, 98, 255, 168, 159, 107, 255, 159, 152, 98, 255, 159, 152, 98, 255, 159, 158, 98, 255, 168, 162, 98, 255, 163, 159, 98, 255, 168, 162, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 142, 141, 91, 255, 110, 108, 77, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 152, 98, 255, 114, 107, 73, 255, 98, 91, 66, 255, 98, 91, 66, 255, 147, 140, 87, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 99, 103, 67, 255, 110, 103, 77, 255, 159, 152, 99, 255, 159, 152, 99, 255, 159, 152, 99, 255, 168, 162, 99, 255, 173, 164, 99, 255, 168, 162, 99, 255, 173, 164, 99, 255, 173, 170, 110, 255, 164, 162, 106, 255, 164, 162, 106, 255, 147, 146, 99, 255, 159, 158, 99, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 110, 108, 77, 255, 143, 141, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 110, 255, 173, 164, 110, 255, 164, 156, 105, 255, 156, 147, 103, 255, 98, 97, 66, 255, 98, 97, 66, 255, 130, 129, 87, 255, 147, 145, 98, 255, 168, 159, 107, 255, 168, 159, 107, 255, 168, 159, 107, 255, 168, 159, 107, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 159, 98, 255, 164, 159, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 142, 141, 91, 255, 110, 108, 77, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 156, 98, 255, 114, 107, 73, 255, 98, 91, 66, 255, 114, 107, 73, 255, 147, 140, 87, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 99, 103, 67, 255, 110, 103, 77, 255, 159, 152, 99, 255, 159, 152, 99, 255, 159, 152, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 159, 158, 99, 255, 173, 164, 99, 255, 173, 170, 110, 255, 164, 162, 106, 255, 164, 162, 106, 255, 156, 153, 103, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 98, 255, 98, 91, 66, 255, 110, 109, 77, 255, 143, 141, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 110, 255, 164, 156, 105, 255, 164, 156, 105, 255, 156, 147, 103, 255, 98, 97, 66, 255, 98, 97, 66, 255, 130, 129, 87, 255, 147, 145, 98, 255, 168, 159, 107, 255, 168, 159, 107, 255, 168, 159, 107, 255, 168, 159, 107, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 142, 141, 91, 255, 110, 108, 77, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 168, 159, 98, 255, 114, 107, 73, 255, 98, 91, 66, 255, 131, 123, 80, 255, 147, 140, 87, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 99, 255, 173, 164, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 99, 103, 67, 255, 110, 103, 77, 255, 159, 152, 99, 255, 159, 152, 99, 255, 159, 152, 99, 255), +"format": "RGBA8", +"height": 64, +"mipmaps": false, +"width": 64 +} + +[sub_resource type="ImageTexture" id="ImageTexture_qws2q"] +image = SubResource("Image_s62qo") + +[node name="PanelContainer" type="PanelContainer"] +offset_right = 107.0 +offset_bottom = 51.0 +focus_mode = 2 +mouse_filter = 1 +theme = ExtResource("3_a3d05") +script = ExtResource("1_bk6mq") +theme_normal = ExtResource("3_a3d05") +theme_selected = ExtResource("1_pvt6l") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 2 +metadata/_edit_lock_ = true + +[node name="TextureRect" type="TextureRect" parent="VBoxContainer"] +layout_mode = 2 +texture = SubResource("ImageTexture_qws2q") +stretch_mode = 3 + +[node name="MaterialName" type="Label" parent="VBoxContainer"] +layout_mode = 2 + +[connection signal="focus_entered" from="." to="." method="_on_focus_entered"] +[connection signal="focus_exited" from="." to="." method="_on_focus_exited"] +[connection signal="tree_exiting" from="." to="." method="_on_tree_exiting"] diff --git a/addons/cyclops_level_builder/docks/material_palette/thumbnail_group.gd b/addons/cyclops_level_builder/docks/material_palette/thumbnail_group.gd new file mode 100644 index 0000000..5f8f092 --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/thumbnail_group.gd @@ -0,0 +1,40 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Resource +class_name ThumbnailGroup + +var thumbnails:Array[MaterialThumbnail] = [] + +func select_thumbnail(obj:MaterialThumbnail): + for t in thumbnails: + t.selected = t == obj + +func add_thumbnail(obj:MaterialThumbnail): + thumbnails.append(obj) + +func remove_thumbnail(obj:MaterialThumbnail): + thumbnails.remove_at(thumbnails.find(obj)) + + diff --git a/addons/cyclops_level_builder/docks/material_palette/thumbnail_normal_theme.tres b/addons/cyclops_level_builder/docks/material_palette/thumbnail_normal_theme.tres new file mode 100644 index 0000000..6a39c73 --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/thumbnail_normal_theme.tres @@ -0,0 +1,17 @@ +[gd_resource type="Theme" load_steps=2 format=3 uid="uid://bx26luxdhj3jq"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_amf1g"] +bg_color = Color(0, 0, 0, 1) +border_width_left = 4 +border_width_top = 4 +border_width_right = 4 +border_width_bottom = 4 +border_color = Color(0, 0, 0, 1) +border_blend = true +corner_radius_top_left = 4 +corner_radius_top_right = 4 +corner_radius_bottom_right = 4 +corner_radius_bottom_left = 4 + +[resource] +PanelContainer/styles/panel = SubResource("StyleBoxFlat_amf1g") diff --git a/addons/cyclops_level_builder/docks/material_palette/thumbnail_selected_theme.tres b/addons/cyclops_level_builder/docks/material_palette/thumbnail_selected_theme.tres new file mode 100644 index 0000000..45ecb6d --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/thumbnail_selected_theme.tres @@ -0,0 +1,16 @@ +[gd_resource type="Theme" load_steps=2 format=3 uid="uid://c0gpl22e2g6ay"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_amf1g"] +bg_color = Color(0, 0, 0, 1) +border_width_left = 4 +border_width_top = 4 +border_width_right = 4 +border_width_bottom = 4 +border_color = Color(1, 0, 0, 1) +corner_radius_top_left = 4 +corner_radius_top_right = 4 +corner_radius_bottom_right = 4 +corner_radius_bottom_left = 4 + +[resource] +PanelContainer/styles/panel = SubResource("StyleBoxFlat_amf1g") diff --git a/addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.gd b/addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.gd new file mode 100644 index 0000000..4420daf --- /dev/null +++ b/addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.gd @@ -0,0 +1,56 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Control +class_name ToolPropertiesDock + +var builder:CyclopsLevelBuilder + + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass + +func set_editor(control:Control): + for child in $ScrollContainer.get_children(): + $ScrollContainer.remove_child(child) + + if control: + $ScrollContainer.add_child(control) + +func save_state(state:Dictionary): + var substate:Dictionary = {} + state["tool_properties"] = substate + + +func load_state(state:Dictionary): + if state == null || !state.has("tool_properties"): + return + + var substate:Dictionary = state["tool_properties"] diff --git a/addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.tscn b/addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.tscn new file mode 100644 index 0000000..3c2a250 --- /dev/null +++ b/addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.tscn @@ -0,0 +1,20 @@ +[gd_scene load_steps=2 format=3 uid="uid://caoy37s0y5a8y"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.gd" id="1_7262j"] + +[node name="Tool Properties" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_7262j") + +[node name="ScrollContainer" type="ScrollContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 diff --git a/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.gd b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.gd new file mode 100644 index 0000000..89221b5 --- /dev/null +++ b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.gd @@ -0,0 +1,79 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends SubViewport +class_name UvEditorPreview + + + +@export var target_material:Material: + get: + return target_material + set(value): + target_material = value + #$Node3D/MeshInstance3D.material_override = target_material + #dirty = true +# var studio:UvEditorPreviewStudio = get_node("UvPreviewStudio") +# studio.target_material = target_material +# if $UvPreviewStudio: +# $UvPreviewStudio.target_material = target_material + dirty = true + +@export var uv_transform:Transform2D = Transform2D.IDENTITY: + get: + return uv_transform + set(value): + if value == uv_transform: + return + uv_transform = value +# dirty = true +# $UvPreviewStudio.uv_transform = uv_transform +# var studio:UvEditorPreviewStudio = get_node("UvPreviewStudio") +# studio.uv_transform = uv_transform +# if $UvPreviewStudio: +# $UvPreviewStudio.uv_transform = uv_transform + dirty = true + +var dirty:bool = true +#var points:PackedVector3Array = [Vector3(0, 0, 0), Vector3(1, 1, 0), Vector3(1, 0, 0), Vector3(0, 1, 0)] + +func take_snapshot()->ImageTexture: + #print ("pre-grabbing image %s" % target_material.resource_path) + await RenderingServer.frame_post_draw + #print ("grabbing image %s" % target_material.resource_path) + var image:Image = get_viewport().get_texture().get_image() + var tex:ImageTexture = ImageTexture.create_from_image(image) + return tex + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + +func _process(delta): + if dirty: + $UvPreviewStudio.target_material = target_material + $UvPreviewStudio.uv_transform = uv_transform + dirty = false + + diff --git a/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.tscn b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.tscn new file mode 100644 index 0000000..0999fdc --- /dev/null +++ b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.tscn @@ -0,0 +1,15 @@ +[gd_scene load_steps=4 format=3 uid="uid://bbfgpupliiqnm"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.gd" id="1_57x0n"] +[ext_resource type="Material" uid="uid://rdhrhgrb78ls" path="res://addons/cyclops_level_builder/materials/grid.tres" id="2_kxmas"] +[ext_resource type="PackedScene" path="res://addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.tscn" id="3_7qfos"] + +[node name="UvPreview" type="SubViewport"] +own_world_3d = true +size = Vector2i(256, 256) +render_target_update_mode = 4 +script = ExtResource("1_57x0n") +target_material = ExtResource("2_kxmas") + +[node name="UvPreviewStudio" parent="." instance=ExtResource("3_7qfos")] +target_material = ExtResource("2_kxmas") diff --git a/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.gd b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.gd new file mode 100644 index 0000000..71449a8 --- /dev/null +++ b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.gd @@ -0,0 +1,67 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Node3D +class_name UvEditorPreviewStudio + + +@export var target_material:Material: + get: + return target_material + set(value): + target_material = value + #$Node3D/MeshInstance3D.material_override = target_material + dirty = true + +@export var uv_transform:Transform2D = Transform2D.IDENTITY: + get: + return uv_transform + set(value): + if value == uv_transform: + return + uv_transform = value + dirty = true + +var dirty:bool = true +var points:PackedVector3Array = [Vector3(-1, 1, 0), Vector3(1, 1, 0), Vector3(-1, -1, 0), Vector3(1, -1, 0)] + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): +# print("_process") + if dirty: + var mesh:ImmediateMesh = ImmediateMesh.new() + + mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLE_STRIP, target_material) + + mesh.surface_set_normal(Vector3(0, 0, 1)) + for p in points: + mesh.surface_set_uv(uv_transform * Vector2(p.x, -p.y)) + mesh.surface_add_vertex(p) + + mesh.surface_end() + +# print("Building preview mesh") + $MeshInstance3D.mesh = mesh + dirty = false diff --git a/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.tscn b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.tscn new file mode 100644 index 0000000..ed9f4f2 --- /dev/null +++ b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=3 format=3] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.gd" id="1_38c8p"] + +[sub_resource type="ImmediateMesh" id="ImmediateMesh_23b3x"] + +[node name="Node3D" type="Node3D"] +script = ExtResource("1_38c8p") + +[node name="Camera3D" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1) +projection = 1 + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +mesh = SubResource("ImmediateMesh_23b3x") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.0684279) diff --git a/addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.gd b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.gd new file mode 100644 index 0000000..a6af64b --- /dev/null +++ b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.gd @@ -0,0 +1,182 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Control +class_name UvEdtiorViewport + +var material_thumbnail_dirty:bool = true + +var target_material:Material +var empty_material:Material + +var uv_transform:Transform2D = Transform2D.IDENTITY + +var builder:CyclopsLevelBuilder: + get: + return builder + set(value): + if builder: + builder.selection_changed.disconnect(on_selection_changed) + + builder = value + + if builder: + builder.selection_changed.connect(on_selection_changed) + +var spin_offset_x:NumbericLineEdit +var spin_offset_y:NumbericLineEdit +var spin_scale_x:NumbericLineEdit +var spin_scale_y:NumbericLineEdit +var spin_rotation:NumbericLineEdit +var spin_skew:NumbericLineEdit + +#var test_slider:EditorSpinSlider + +# Called when the node enters the scene tree for the first time. +func _ready(): + empty_material = StandardMaterial3D.new() + empty_material.albedo_color = Color.BLACK + + spin_offset_x = $VBoxContainer/GridContainer2/HBoxContainer2/offset_x + spin_offset_y = $VBoxContainer/GridContainer2/HBoxContainer/offset_y + spin_scale_x = $VBoxContainer/GridContainer3/HBoxContainer2/scale_x + spin_scale_y = $VBoxContainer/GridContainer3/HBoxContainer/scale_y + spin_rotation = $VBoxContainer/GridContainer4/HBoxContainer2/rotation + spin_skew = $VBoxContainer/GridContainer4/HBoxContainer/skew + +# test_slider = EditorSpinSlider.new() +# test_slider.size_flags_horizontal = Control.SIZE_EXPAND +# $VBoxContainer.add_child(test_slider) + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + + if material_thumbnail_dirty: + material_thumbnail_dirty = false + + $UvPreview.target_material = target_material + $UvPreview.uv_transform = uv_transform + + var tex:ImageTexture = await $UvPreview.take_snapshot() + $VBoxContainer/Preview.texture = tex + pass + +func on_selection_changed(): + material_thumbnail_dirty = true + target_material = empty_material + + if builder.active_node: + var block:CyclopsConvexBlock = builder.active_node.get_active_block() + if block: + var vol:ConvexVolume = block.control_mesh + var face_idx = vol.active_face if vol.active_face != -1 else 0 + + var f:ConvexVolume.FaceInfo = vol.get_face(face_idx) + + + spin_offset_x.value = f.uv_transform.origin.x + spin_offset_y.value = f.uv_transform.origin.y + spin_scale_x.value = f.uv_transform.get_scale().x + spin_scale_y.value = f.uv_transform.get_scale().y + spin_rotation.value = rad_to_deg(f.uv_transform.get_rotation()) + spin_skew.value = rad_to_deg(f.uv_transform.get_skew()) + + if f.material_id != -1: + var mat:Material = block.materials[f.material_id] + target_material = mat + else: + target_material = null + + uv_transform = f.uv_transform + + + +func save_state(state:Dictionary): + var substate:Dictionary = {} + state["uv_editor_dock"] = substate + +# substate["materials"] = material_list.duplicate() + +func load_state(state:Dictionary): + if state == null || !state.has("uv_editor_dock"): + return + + var substate:Dictionary = state["uv_editor_dock"] + + +func apply_uv_transform(): + var xform:Transform2D = Transform2D(deg_to_rad(spin_rotation.value), \ + Vector2(spin_scale_x.value, spin_scale_y.value), \ + deg_to_rad(spin_skew.value), \ + Vector2(spin_offset_x.value, spin_offset_y.value)) + + uv_transform = xform + + var cmd:CommandSetUvTransform = CommandSetUvTransform.new() + cmd.builder = builder + cmd.uv_transform = xform + +# print("setting xform %s " % xform) + + if builder.active_node: + for child in builder.active_node.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + var vol:ConvexVolume = block.control_mesh + for f_idx in vol.faces.size(): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + if f.selected: + cmd.add_face(block.get_path(), f_idx) + + + if cmd.will_change_anything(): + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo) + + +func _on_offset_x_value_changed(value): + apply_uv_transform() + + +func _on_offset_y_value_changed(value): + apply_uv_transform() + + +func _on_scale_x_value_changed(value): + apply_uv_transform() + + +func _on_scale_y_value_changed(value): + apply_uv_transform() + + +func _on_rotation_value_changed(value): + apply_uv_transform() + + +func _on_skew_value_changed(value): + apply_uv_transform() + + diff --git a/addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.tscn b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.tscn new file mode 100644 index 0000000..dba3249 --- /dev/null +++ b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.tscn @@ -0,0 +1,143 @@ +[gd_scene load_steps=6 format=3] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.gd" id="1_rk116"] +[ext_resource type="PackedScene" uid="uid://diibmlqy1mpqb" path="res://addons/cyclops_level_builder/controls/numeric_line_edit.tscn" id="2_cekit"] +[ext_resource type="PackedScene" path="res://addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.tscn" id="2_kpj7h"] + +[sub_resource type="Image" id="Image_me1xa"] +data = { +"data": PackedByteArray(155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255), +"format": "RGBA8", +"height": 128, +"mipmaps": false, +"width": 128 +} + +[sub_resource type="ImageTexture" id="ImageTexture_0xrmf"] +image = SubResource("Image_me1xa") + +[node name="Uv Transform" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_right = -697.0 +offset_bottom = -285.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_rk116") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +metadata/_edit_lock_ = true + +[node name="Preview" type="TextureRect" parent="VBoxContainer"] +layout_mode = 2 +texture = SubResource("ImageTexture_0xrmf") +stretch_mode = 3 + +[node name="GridContainer2" type="GridContainer" parent="VBoxContainer"] +layout_mode = 2 +columns = 2 + +[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer/GridContainer2"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label" type="Label" parent="VBoxContainer/GridContainer2/HBoxContainer2"] +layout_mode = 2 +text = "Offset X +" + +[node name="offset_x" parent="VBoxContainer/GridContainer2/HBoxContainer2" instance=ExtResource("2_cekit")] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/GridContainer2"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label2" type="Label" parent="VBoxContainer/GridContainer2/HBoxContainer"] +layout_mode = 2 +text = "Offset Y +" + +[node name="offset_y" parent="VBoxContainer/GridContainer2/HBoxContainer" instance=ExtResource("2_cekit")] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="GridContainer3" type="GridContainer" parent="VBoxContainer"] +layout_mode = 2 +columns = 2 + +[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer/GridContainer3"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label" type="Label" parent="VBoxContainer/GridContainer3/HBoxContainer2"] +layout_mode = 2 +text = "Scale X +" + +[node name="scale_x" parent="VBoxContainer/GridContainer3/HBoxContainer2" instance=ExtResource("2_cekit")] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/GridContainer3"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label2" type="Label" parent="VBoxContainer/GridContainer3/HBoxContainer"] +layout_mode = 2 +text = "Scale Y" + +[node name="scale_y" parent="VBoxContainer/GridContainer3/HBoxContainer" instance=ExtResource("2_cekit")] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="GridContainer4" type="GridContainer" parent="VBoxContainer"] +layout_mode = 2 +columns = 2 + +[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer/GridContainer4"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label" type="Label" parent="VBoxContainer/GridContainer4/HBoxContainer2"] +layout_mode = 2 +text = "Rotation" + +[node name="rotation" parent="VBoxContainer/GridContainer4/HBoxContainer2" instance=ExtResource("2_cekit")] +layout_mode = 2 +size_flags_horizontal = 3 +snap_size = 15.0 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/GridContainer4"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label2" type="Label" parent="VBoxContainer/GridContainer4/HBoxContainer"] +layout_mode = 2 +text = "Skew +" + +[node name="skew" parent="VBoxContainer/GridContainer4/HBoxContainer" instance=ExtResource("2_cekit")] +layout_mode = 2 +size_flags_horizontal = 3 +snap_size = 15.0 + +[node name="UvPreview" parent="." instance=ExtResource("2_kpj7h")] +size = Vector2i(128, 128) +target_material = null + +[connection signal="value_changed" from="VBoxContainer/GridContainer2/HBoxContainer2/offset_x" to="." method="_on_offset_x_value_changed"] +[connection signal="value_changed" from="VBoxContainer/GridContainer2/HBoxContainer/offset_y" to="." method="_on_offset_y_value_changed"] +[connection signal="value_changed" from="VBoxContainer/GridContainer3/HBoxContainer2/scale_x" to="." method="_on_scale_x_value_changed"] +[connection signal="value_changed" from="VBoxContainer/GridContainer3/HBoxContainer/scale_y" to="." method="_on_scale_y_value_changed"] +[connection signal="value_changed" from="VBoxContainer/GridContainer4/HBoxContainer2/rotation" to="." method="_on_rotation_value_changed"] +[connection signal="value_changed" from="VBoxContainer/GridContainer4/HBoxContainer/skew" to="." method="_on_skew_value_changed"] diff --git a/addons/cyclops_level_builder/handles/handle_edge.gd b/addons/cyclops_level_builder/handles/handle_edge.gd new file mode 100644 index 0000000..377de50 --- /dev/null +++ b/addons/cyclops_level_builder/handles/handle_edge.gd @@ -0,0 +1,40 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends RefCounted +class_name HandleEdge + +var edge_index:int +#var p0:Vector3 +#var p1:Vector3 +#var p0_init:Vector3 +#var p1_init:Vector3 +var p_ref:Vector3 #Centroid +var p_ref_init:Vector3 +var block_path:NodePath + + +func _to_string(): +# return "%s init pos %s %s pos %s %s" % [block_path, initial_p0, initial_p1, p0, p1] + return "edge %s e_idx:%s p_ref:%s p_ref_init:%s" % [block_path, edge_index, p_ref, p_ref_init] diff --git a/addons/cyclops_level_builder/handles/handle_face.gd b/addons/cyclops_level_builder/handles/handle_face.gd new file mode 100644 index 0000000..8afe42f --- /dev/null +++ b/addons/cyclops_level_builder/handles/handle_face.gd @@ -0,0 +1,37 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends RefCounted +class_name HandleFace + +var face_index:int +var face_id:int +var p_ref:Vector3 #Centroid +var p_ref_init:Vector3 +var block_path:NodePath + + +func _to_string(): +# return "%s init pos %s %s pos %s %s" % [block_path, initial_p0, initial_p1, p0, p1] + return "face %s idx:%s ref_%s ref_init:%s" % [block_path.get_name(block_path.get_name_count() - 1), face_index, p_ref, p_ref_init] diff --git a/addons/cyclops_level_builder/handles/handle_vertex.gd b/addons/cyclops_level_builder/handles/handle_vertex.gd new file mode 100644 index 0000000..af89b77 --- /dev/null +++ b/addons/cyclops_level_builder/handles/handle_vertex.gd @@ -0,0 +1,36 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends RefCounted +class_name HandleVertex + +var vertex_index:int +var position:Vector3 +#var id:int #Label to link this vertex back to whatever is being tracked +var initial_position:Vector3 +var block_path:NodePath + + +func _to_string(): + return "%s init pos %s pos %s" % [block_path, initial_position, position] diff --git a/addons/cyclops_level_builder/materials/grid.tres b/addons/cyclops_level_builder/materials/grid.tres new file mode 100644 index 0000000..ee80492 --- /dev/null +++ b/addons/cyclops_level_builder/materials/grid.tres @@ -0,0 +1,10 @@ +[gd_resource type="StandardMaterial3D" load_steps=3 format=3 uid="uid://rdhrhgrb78ls"] + +[ext_resource type="Texture2D" uid="uid://bnlqi20ay4vs1" path="res://addons/cyclops_level_builder/art/textures/grid_cell2.png" id="1_17wu6"] +[ext_resource type="Texture2D" uid="uid://b78mg60xhic6n" path="res://addons/cyclops_level_builder/art/textures/checkerboard.png" id="1_ldry2"] + +[resource] +vertex_color_use_as_albedo = true +albedo_texture = ExtResource("1_ldry2") +roughness_texture = ExtResource("1_17wu6") +texture_filter = 5 diff --git a/addons/cyclops_level_builder/materials/outline_material.tres b/addons/cyclops_level_builder/materials/outline_material.tres new file mode 100644 index 0000000..fc4196a --- /dev/null +++ b/addons/cyclops_level_builder/materials/outline_material.tres @@ -0,0 +1,8 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://kw5ymmorwkvp"] + +[ext_resource type="Shader" uid="uid://cc5tovf48xmg1" path="res://addons/cyclops_level_builder/shaders/outline_shader.tres" id="1_i1fkq"] + +[resource] +render_priority = 0 +shader = ExtResource("1_i1fkq") +shader_parameter/ColorParameter = Color(0, 0, 0, 1) diff --git a/addons/cyclops_level_builder/materials/tool_edit_active_fill_material.tres b/addons/cyclops_level_builder/materials/tool_edit_active_fill_material.tres new file mode 100644 index 0000000..25ab946 --- /dev/null +++ b/addons/cyclops_level_builder/materials/tool_edit_active_fill_material.tres @@ -0,0 +1,9 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://dv5gwbhe5pg64"] + +[resource] +render_priority = 1 +transparency = 1 +albedo_color = Color(0, 0, 0, 0.501961) +emission_enabled = true +emission = Color(1, 1, 1, 1) +grow_amount = 0.1 diff --git a/addons/cyclops_level_builder/materials/tool_edit_active_material.tres b/addons/cyclops_level_builder/materials/tool_edit_active_material.tres new file mode 100644 index 0000000..2472241 --- /dev/null +++ b/addons/cyclops_level_builder/materials/tool_edit_active_material.tres @@ -0,0 +1,8 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://dneusleqxicge"] + +[resource] +render_priority = 1 +albedo_color = Color(0, 0, 0, 1) +emission_enabled = true +emission = Color(1, 1, 1, 1) +grow_amount = 0.1 diff --git a/addons/cyclops_level_builder/materials/tool_edit_selected_fill_material.tres b/addons/cyclops_level_builder/materials/tool_edit_selected_fill_material.tres new file mode 100644 index 0000000..f47984c --- /dev/null +++ b/addons/cyclops_level_builder/materials/tool_edit_selected_fill_material.tres @@ -0,0 +1,9 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://b20sku4kdojbr"] + +[resource] +render_priority = 1 +transparency = 1 +albedo_color = Color(0, 0, 0, 0.501961) +emission_enabled = true +emission = Color(1, 0.466667, 0.109804, 1) +grow_amount = 0.1 diff --git a/addons/cyclops_level_builder/materials/tool_edit_selected_material.tres b/addons/cyclops_level_builder/materials/tool_edit_selected_material.tres new file mode 100644 index 0000000..d634b72 --- /dev/null +++ b/addons/cyclops_level_builder/materials/tool_edit_selected_material.tres @@ -0,0 +1,9 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://cmr7csndcasyp"] + +[resource] +render_priority = 1 +transparency = 4 +albedo_color = Color(0, 0, 0, 1) +emission_enabled = true +emission = Color(1, 0.466667, 0.109804, 1) +grow_amount = 0.1 diff --git a/addons/cyclops_level_builder/materials/tool_edit_unselected_material.tres b/addons/cyclops_level_builder/materials/tool_edit_unselected_material.tres new file mode 100644 index 0000000..ffaca44 --- /dev/null +++ b/addons/cyclops_level_builder/materials/tool_edit_unselected_material.tres @@ -0,0 +1,8 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://ff2cjjfaaqfb"] + +[resource] +render_priority = 1 +transparency = 4 +albedo_color = Color(0, 0, 0, 1) +emission_enabled = true +grow_amount = 0.1 diff --git a/addons/cyclops_level_builder/materials/tool_material.tres b/addons/cyclops_level_builder/materials/tool_material.tres new file mode 100644 index 0000000..48dfa0c --- /dev/null +++ b/addons/cyclops_level_builder/materials/tool_material.tres @@ -0,0 +1,9 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://bm85lvfgttrlj"] + +[resource] +render_priority = 1 +transparency = 4 +albedo_color = Color(0, 0, 0, 1) +emission_enabled = true +emission = Color(1, 1, 0, 1) +grow_amount = 0.1 diff --git a/addons/cyclops_level_builder/materials/tool_object_active_material.tres b/addons/cyclops_level_builder/materials/tool_object_active_material.tres new file mode 100644 index 0000000..6f666b9 --- /dev/null +++ b/addons/cyclops_level_builder/materials/tool_object_active_material.tres @@ -0,0 +1,10 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://dcr6mnkfw7mvh"] + +[resource] +render_priority = 1 +transparency = 4 +no_depth_test = true +albedo_color = Color(0, 0, 0, 1) +emission_enabled = true +emission = Color(1, 0.717647, 0.529412, 1) +grow_amount = 0.1 diff --git a/addons/cyclops_level_builder/materials/tool_object_selected_material.tres b/addons/cyclops_level_builder/materials/tool_object_selected_material.tres new file mode 100644 index 0000000..e08c765 --- /dev/null +++ b/addons/cyclops_level_builder/materials/tool_object_selected_material.tres @@ -0,0 +1,10 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://bscbhmr84pnpx"] + +[resource] +render_priority = 1 +transparency = 4 +no_depth_test = true +albedo_color = Color(0, 0, 0, 1) +emission_enabled = true +emission = Color(1, 0.494118, 0.160784, 1) +grow_amount = 0.1 diff --git a/addons/cyclops_level_builder/math/convex_volume.gd b/addons/cyclops_level_builder/math/convex_volume.gd new file mode 100644 index 0000000..56f5772 --- /dev/null +++ b/addons/cyclops_level_builder/math/convex_volume.gd @@ -0,0 +1,928 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends RefCounted +class_name ConvexVolume + + +class VertexInfo extends RefCounted: + var mesh:ConvexVolume + #var index:int + var point:Vector3 + var normal:Vector3 + var edge_indices:Array[int] = [] + var selected:bool + #var active:bool + + func _init(mesh:ConvexVolume, point:Vector3 = Vector3.ZERO): + self.mesh = mesh + self.point = point + + func _to_string(): + var s:String = "%s [" % [point] + for i in edge_indices: + s += "%s " % i + s += "]" + + return s + +class EdgeInfo extends RefCounted: + var mesh:ConvexVolume + var start_index:int + var end_index:int + var face_indices:Array[int] = [] + var selected:bool + #var active:bool + + func _init(mesh:ConvexVolume, start:int = 0, end:int = 0): + self.mesh = mesh + start_index = start + end_index = end + + func _to_string(): + var s:String = "%s %s [" % [start_index, end_index] + for i in face_indices: + s += "%s " % i + s += "]" + return s + + +class FaceInfo extends RefCounted: + var mesh:ConvexVolume + var id:int + var normal:Vector3 #Face normal points in direction of interior + var material_id:int + var uv_transform:Transform2D + var selected:bool + #var active:bool + var vertex_indices:Array[int] + var triangulation_indices:Array[int] + var lightmap_uvs:PackedVector2Array + + func _init(mesh:ConvexVolume, id:int, normal:Vector3, uv_transform:Transform2D = Transform2D.IDENTITY, material_id:int = 0, selected:bool = false): + self.mesh = mesh + self.id = id + self.normal = normal + self.material_id = material_id + self.uv_transform = uv_transform + self.selected = selected + + func get_plane()->Plane: + return Plane(normal, mesh.vertices[vertex_indices[0]].point) + + func get_points()->PackedVector3Array: + var result:PackedVector3Array + for i in vertex_indices: + result.append(mesh.vertices[i].point) + return result + + func get_centroid()->Vector3: + var points:PackedVector3Array = get_points() + var center:Vector3 + for p in points: + center += p + center /= points.size() + return center + +# func get_triangulation()->Array[int]: +# if triangulation_indices.is_empty(): +# var points:PackedVector3Array +# var indices:Array[int] +# for v_idx in vertex_indices: +# points.append(mesh.vertices[v_idx].point) +# indices.append(v_idx) +# +## print("start points %s" % points) +# +# var normal:Vector3 = MathUtil.face_area_x2(points).normalized() +## print("normal %s" % normal) +# triangulation_indices = MathUtil.trianglate_face_indices(points, indices, normal) +## print("triangulation %s" % str(triangulation_indices)) +# +# return triangulation_indices + + func get_triangulation()->Array[int]: + if triangulation_indices.is_empty(): + var points:PackedVector3Array + for v_idx in vertex_indices: + points.append(mesh.vertices[v_idx].point) + +# print("start points %s" % points) + + var normal:Vector3 = MathUtil.face_area_x2(points).normalized() +# print("normal %s" % normal) + triangulation_indices = MathUtil.trianglate_face_vertex_indices(points, normal) +# print("triangulation %s" % str(triangulation_indices)) + + return triangulation_indices + + func get_trianges()->PackedVector3Array: + var indices:Array[int] = get_triangulation() + var result:PackedVector3Array + + for fv_idx in indices: + var v_idx:int = vertex_indices[fv_idx] + result.append(mesh.vertices[v_idx].point) + +# print("triangules %s" % result) + + return result + + func reverse(): + normal = -normal + vertex_indices.reverse() + triangulation_indices.clear() + +#class FaceVertexInfo extends RefCounted: +# var vert_idx:int +# var face_idx:int + + + +var vertices:Array[VertexInfo] = [] +var edges:Array[EdgeInfo] = [] +var faces:Array[FaceInfo] = [] +var bounds:AABB + +var lightmap_uvs_dirty = true + +var active_vertex:int = -1 +var active_edge:int = -1 +var active_face:int = -1 + +func _to_string()->String: + var result:String = "" + for v in vertices: + result += str(v.point) + ", " + return result + + +func init_block(block_bounds:AABB, uv_transform:Transform2D = Transform2D.IDENTITY, material_id:int = -1): + var p000:Vector3 = block_bounds.position + var p111:Vector3 = block_bounds.end + var p001:Vector3 = Vector3(p000.x, p000.y, p111.z) + var p010:Vector3 = Vector3(p000.x, p111.y, p000.z) + var p011:Vector3 = Vector3(p000.x, p111.y, p111.z) + var p100:Vector3 = Vector3(p111.x, p000.y, p000.z) + var p101:Vector3 = Vector3(p111.x, p000.y, p111.z) + var p110:Vector3 = Vector3(p111.x, p111.y, p000.z) + + init_prism([p000, p001, p011, p010], p100 - p000, uv_transform, material_id) + + +func init_prism(base_points:Array[Vector3], extrude_dir:Vector3, uv_transform:Transform2D = Transform2D.IDENTITY, material_id:int = -1): + vertices = [] + edges = [] + faces = [] + var base_normal = -extrude_dir.normalized() + + var face_area_x2:Vector3 = MathUtil.face_area_x2(base_points) + if face_area_x2.dot(extrude_dir) > 0: + base_points.reverse() + + for p in base_points: + var v:VertexInfo = VertexInfo.new(self, p) + vertices.append(v) + for p in base_points: + var v:VertexInfo = VertexInfo.new(self, p + extrude_dir) + vertices.append(v) + + var f0:FaceInfo = FaceInfo.new(self, faces.size(), base_normal, uv_transform, material_id) + f0.vertex_indices = [] + f0.vertex_indices.append_array(range(base_points.size())) + faces.append(f0) + var f1:FaceInfo = FaceInfo.new(self, faces.size(), -base_normal, uv_transform, material_id) + f1.vertex_indices = [] + f1.vertex_indices.append_array(range(base_points.size(), base_points.size() * 2)) + f1.vertex_indices.reverse() + faces.append(f1) + + + for i in base_points.size(): + var p_idx0:int = i + var p_idx1:int = wrap(i + 1, 0, base_points.size()) + + var v0:VertexInfo = vertices[p_idx0] + var v1:VertexInfo = vertices[p_idx1] + + var normal = base_normal.cross(v1.point - v0.point).normalized() + var f:FaceInfo = FaceInfo.new(self, faces.size(), normal, uv_transform, material_id) + f.vertex_indices = [p_idx1, p_idx0, p_idx0 + base_points.size(), p_idx1 + base_points.size()] + faces.append(f) + + build_edges() + calc_vertex_normals() + + bounds = calc_bounds() + calc_lightmap_uvs() + +func init_from_convex_block_data(data:ConvexBlockData): + vertices = [] + edges = [] + faces = [] + + active_vertex = data.active_vertex + active_edge = data.active_edge + active_face = data.active_face + + for i in data.vertex_points.size(): + var v:VertexInfo = VertexInfo.new(self, data.vertex_points[i]) + vertices.append(v) + v.selected = data.vertex_selected[i] + #v.active = data.vertex_active[i] + + var num_edges:int = data.edge_vertex_indices.size() / 2 + for i in num_edges: + var edge:EdgeInfo = EdgeInfo.new(self, data.edge_vertex_indices[i * 2], data.edge_vertex_indices[i * 2 + 1]) + edges.append(edge) + edge.face_indices.append(data.edge_face_indices[i * 2]) + edge.face_indices.append(data.edge_face_indices[i * 2 + 1]) + edge.selected = data.edge_selected[i] + #edge.active = data.edge_active[i] + + var face_vertex_count:int = 0 + for face_idx in data.face_vertex_count.size(): + var num_verts:int = data.face_vertex_count[face_idx] + var vert_indices:Array[int] + var vert_points:PackedVector3Array + for i in num_verts: + var vert_idx:int = data.face_vertex_indices[face_vertex_count] + vert_indices.append(vert_idx) + vert_points.append(vertices[vert_idx].point) +# var v_idx:int = data.face_vertex_indices[count] + face_vertex_count += 1 + + var normal = MathUtil.face_area_x2(vert_points).normalized() + var f:FaceInfo = FaceInfo.new(self, data.face_ids[face_idx], normal, data.face_uv_transform[face_idx], data.face_material_indices[face_idx]) + f.selected = data.face_selected[face_idx] + #f.active = data.face_active[face_idx] + f.vertex_indices = vert_indices + + faces.append(f) + + + calc_vertex_normals() + + bounds = calc_bounds() + calc_lightmap_uvs() + #print("init_from_convex_block_data %s" % format_faces_string()) + + +#Calc convex hull bouding points +func init_from_points(points:PackedVector3Array, uv_transform:Transform2D = Transform2D.IDENTITY, material_id:int = -1): + vertices = [] + edges = [] + faces = [] + + #print("init_from_points %s" % points) + var hull:QuickHull.Hull = QuickHull.quickhull(points) + #print("hull %s" % hull.format_points()) + + var hull_points:Array[Vector3] = hull.get_points() + + for p in hull_points: + vertices.append(VertexInfo.new(self, p)) + + for facet in hull.facets: + var plane:Plane = facet.plane + var vert_indices:Array[int] = [] + + for p in facet.points: + var vert_idx:int = hull_points.find(p) + vert_indices.append(vert_idx) + + var f:FaceInfo = FaceInfo.new(self, faces.size(), plane.normal, uv_transform, material_id) + f.vertex_indices = vert_indices + faces.append(f) + + + build_edges() + calc_vertex_normals() + + bounds = calc_bounds() + calc_lightmap_uvs() + +func calc_vertex_normals(): + for v_idx in vertices.size(): + var v:VertexInfo = vertices[v_idx] + var weighted_normal:Vector3 + + for face in faces: + if face.vertex_indices.has(v_idx): + weighted_normal += MathUtil.face_area_x2(face.get_points()) + + v.normal = weighted_normal.normalized() + + +func get_edge(vert_idx0:int, vert_idx1:int)->EdgeInfo: + for e in edges: + if e.start_index == vert_idx0 && e.end_index == vert_idx1: + return e + if e.start_index == vert_idx1 && e.end_index == vert_idx0: + return e + return null + + +func build_edges(): + + #Calculate edges + for face in faces: + var num_corners = face.vertex_indices.size() + for i0 in num_corners: + var i1:int = wrap(i0 + 1, 0, num_corners) + var v0_idx:int = face.vertex_indices[i0] + var v1_idx:int = face.vertex_indices[i1] + + var edge:EdgeInfo = get_edge(v0_idx, v1_idx) + if !edge: + var edge_idx = edges.size() + edge = EdgeInfo.new(self, v0_idx, v1_idx) + edges.append(edge) + + var v0:VertexInfo = vertices[v0_idx] + v0.edge_indices.append(edge_idx) + + var v1:VertexInfo = vertices[v1_idx] + v1.edge_indices.append(edge_idx) + + edge.face_indices.append(face.id) + +func get_face_coincident_with_plane(plane:Plane)->FaceInfo: + for f in faces: + var p:Plane = f.get_plane() + if p.is_equal_approx(plane): + return f + return null + + +func get_face_ids(selected_only:bool = false)->PackedInt32Array: + var result:PackedInt32Array + for f in faces: + if !selected_only || f.selected: + result.append(f.id) + return result + +func get_face_indices(selected_only:bool = false)->PackedInt32Array: + var result:PackedInt32Array + for f_idx in faces.size(): + var f:FaceInfo = faces[f_idx] + if !selected_only || f.selected: + result.append(f_idx) + return result + +func get_trimesh_indices()->PackedInt32Array: + var result:PackedInt32Array + + for f in faces: + for fv_idx in f.get_triangulation(): + var v_idx:int = f.vertex_indices[fv_idx] + result.append(v_idx) + + return result + +func get_face_most_similar_to_plane(plane:Plane)->FaceInfo: + var best_dot:float = -1 + var best_face:FaceInfo + + for f in faces: + var p:Plane = f.get_plane() + var dot = p.normal.dot(plane.normal) + if dot >= best_dot: + best_dot = dot + best_face = f + return best_face + +func copy_face_attributes(ref_vol:ConvexVolume): + for fl in faces: + var ref_face:FaceInfo = ref_vol.get_face_most_similar_to_plane(fl.get_plane()) + + fl.material_id = ref_face.material_id + fl.uv_transform = ref_face.uv_transform + fl.selected = ref_face.selected + +func to_convex_block_data()->ConvexBlockData: + var result:ConvexBlockData = ConvexBlockData.new() + + result.active_vertex = active_vertex + result.active_edge = active_edge + result.active_face = active_face + + for v in vertices: + result.vertex_points.append(v.point) + result.vertex_selected.append(v.selected) + #result.vertex_active.append(v.active) + + for e in edges: + result.edge_vertex_indices.append_array([e.start_index, e.end_index]) + result.edge_face_indices.append_array([e.face_indices[0], e.face_indices[1]]) + result.edge_selected.append(e.selected) + #result.edge_active.append(e.active) + + for face in faces: + var num_verts:int = face.vertex_indices.size() + result.face_vertex_count.append(num_verts) + result.face_vertex_indices.append_array(face.vertex_indices) + result.face_ids.append(face.id) + result.face_selected.append(face.selected) + #result.face_active.append(face.active) + result.face_material_indices.append(face.material_id) + result.face_uv_transform.append(face.uv_transform) + + return result + +func get_face(face_id:int)->FaceInfo: + for face in faces: + if face.id == face_id: + return face + return null + +# Creates a new volume that is equal to the portion of this volume on the top +# side of the passed plane. Does not modify the geometry of this volume. +func cut_with_plane(plane:Plane, uv_transform:Transform2D = Transform2D.IDENTITY, material_id:int = 0)->ConvexVolume: +# + var planes:Array[Plane] + for f in faces: + #Top of planr should point toward interior + planes.append(MathUtil.flip_plane(f.get_plane())) + planes.append(plane) + + #print("planes %s" % GeneralUtil.format_planes_string(planes)) + + var hull_points:Array[Vector3] = MathUtil.get_convex_hull_points_from_planes(planes) + if hull_points.is_empty(): + return null + + var new_vol:ConvexVolume = ConvexVolume.new() + new_vol.init_from_points(hull_points) + + new_vol.copy_face_attributes(self) + + for f in new_vol.faces: + var f_plane:Plane = MathUtil.flip_plane(f.get_plane()) + if f_plane.is_equal_approx(plane): + f.uv_transform = uv_transform + f.material_id = material_id + break + + return new_vol + +func is_empty(): + return bounds.size.is_zero_approx() + +# Returns a new ConvexVolume equal to this volume after the plane of the +# indicated face has been translated the given offset. Does not modify the +# geometry of this volume. +func translate_face_plane(face_id:int, offset:Vector3, lock_uvs:bool = false)->ConvexVolume: + var xform:Transform3D = Transform3D(Basis.IDENTITY, -offset) + + var source_face:FaceInfo + var transformed_plane:Plane + + var planes:Array[Plane] = [] + for f in faces: + if f.id == face_id: + transformed_plane = MathUtil.flip_plane(f.get_plane()) * xform + planes.append(transformed_plane) + source_face = f + else: + planes.append(MathUtil.flip_plane(f.get_plane())) + + #print("planes %s" % str(planes)) + var hull_points:Array[Vector3] = MathUtil.get_convex_hull_points_from_planes(planes) + if hull_points.is_empty(): + return null + + var new_vol:ConvexVolume = ConvexVolume.new() + new_vol.init_from_points(hull_points) + new_vol.copy_face_attributes(self) + + return new_vol + +func translate(offset:Vector3, lock_uvs:bool = false): + transform(Transform3D(Basis.IDENTITY, offset), lock_uvs) + + +func transform(xform:Transform3D, lock_uvs:bool = false): + for v in vertices: + v.point = xform * v.point + + if xform.basis.determinant() < 0: + for f in faces: + f.reverse() + + if lock_uvs: +# var xform_inv:Transform3D = xform.affine_inverse() + #var xform_inv:Transform3D = xform + #print("--xform %s" % xform) + + for f in faces: + var axis:MathUtil.Axis = MathUtil.get_longest_axis(f.normal) + + match axis: + MathUtil.Axis.X: + var orig_p:Vector3 = xform.origin + var u_p:Vector3 = xform * Vector3(0, 0, 1) - orig_p + var v_p:Vector3 = xform * Vector3(0, 1, 0) - orig_p + var move_xform:Transform2D = Transform2D(Vector2(u_p.z, u_p.y), \ + Vector2(v_p.z, v_p.y), \ + Vector2(orig_p.z, orig_p.y)) + + f.uv_transform = f.uv_transform * move_xform + + MathUtil.Axis.Y: + var orig_p:Vector3 = xform.origin + var u_p:Vector3 = xform * Vector3(1, 0, 0) - orig_p + var v_p:Vector3 = xform * Vector3(0, 0, 1) - orig_p + var move_xform:Transform2D = Transform2D(Vector2(u_p.x, u_p.z), \ + Vector2(v_p.x, v_p.z), \ + Vector2(orig_p.x, orig_p.z)) + + f.uv_transform = f.uv_transform * move_xform + + MathUtil.Axis.Z: + #var xform_inv = xform.affine_inverse() + var orig_p:Vector3 = xform.origin + var u_p:Vector3 = xform * Vector3(1, 0, 0) - orig_p + var v_p:Vector3 = xform * Vector3(0, 1, 0) - orig_p + var move_xform:Transform2D = Transform2D(Vector2(u_p.x, u_p.y), \ + Vector2(v_p.x, v_p.y), \ + Vector2(orig_p.x, orig_p.y)) + + f.uv_transform = f.uv_transform * move_xform + + #calc_lightmap_uvs() + +func unused_face_id()->int: + var idx = 0 + for p in faces: + idx = max(idx, p.id) + return idx + 1 + +func contains_point(point:Vector3)->bool: + for f in faces: + var plane:Plane = f.get_plane() + if !plane.has_point(point) && !plane.is_point_over(point): + return false + return true + + +func get_points()->PackedVector3Array: + var points:PackedVector3Array + + for v in vertices: + points.append(v.point) + + return points + +func calc_bounds()->AABB: + if vertices.is_empty(): + return AABB() + + var result:AABB = AABB(vertices[0].point, Vector3.ZERO) + + for v_idx in range(1, vertices.size()): + result = result.expand(vertices[v_idx].point) + + return result + + +func tristrip_vertex_range(num_verts:int)->PackedInt32Array: + var result:PackedInt32Array + + result.append(0) + result.append(1) + for i in range(2, num_verts): + if (i & 1) == 0: + result.append(num_verts - (i >> 1)) + else: + result.append((i >> 1) + 1) + + return result + +func tristrip_vertex_range_reverse(num_verts:int)->PackedInt32Array: + var result:PackedInt32Array + + result.append(1) + result.append(0) + for i in range(2, num_verts): + if (i & 1) == 0: + result.append((i >> 1) + 1) + else: + result.append(num_verts - (i >> 1)) + + return result + +func calc_lightmap_uvs(): + var packer:FacePacker = FacePacker.new() + var max_dim:float = max(bounds.size.x, bounds.size.y, bounds.size.z) + var tree:FacePacker.FaceTree = packer.build_faces(self, max_dim * .1) + + var xform:Transform2D = Transform2D.IDENTITY + xform = xform.scaled(tree.bounds.size) + var xform_inv = xform.affine_inverse() + + for ft in tree.face_list: + var face:FaceInfo = faces[ft.face_index] + face.lightmap_uvs = xform_inv * ft.points + +func create_mesh(material_list:Array[Material], default_material:Material)->ArrayMesh: +# if Engine.is_editor_hint(): +# return +# print("num faces %s" % faces.size()) +# print("-creating mesh") + + var mesh:ArrayMesh = ArrayMesh.new() + mesh.blend_shape_mode = Mesh.BLEND_SHAPE_MODE_NORMALIZED + mesh.lightmap_size_hint = Vector2(1000, 1000) + + var shadow_mesh:ArrayMesh = ArrayMesh.new() + shadow_mesh.blend_shape_mode = Mesh.BLEND_SHAPE_MODE_NORMALIZED + + var face_dict:Dictionary = {} + for f_idx in faces.size(): +# print("check F_idx %s" % f_idx) + var face:FaceInfo = faces[f_idx] + if face_dict.has(face.material_id): + var arr = face_dict[face.material_id] + arr.append(f_idx) +# print("arr %s" % [arr]) + face_dict[face.material_id] = arr +# print("append %s to %s" % [f_idx, face.material_id]) + else: + face_dict[face.material_id] = [f_idx] +# print("starting %s to %s" % [f_idx, face.material_id]) + + var surface_idx:int = 0 + for mat_id in face_dict.keys(): +# print("surface mat grp %s" % mat_id) + + var points:PackedVector3Array + var normals:PackedVector3Array + var uv1s:PackedVector2Array + var uv2s:PackedVector2Array + + var material = default_material + if mat_id >= 0 && mat_id < material_list.size(): + material = material_list[mat_id] + + for f_idx in face_dict[mat_id]: +# print("f_idx %s" % f_idx) + + var face:FaceInfo = faces[f_idx] + + + var axis:MathUtil.Axis = MathUtil.get_longest_axis(face.normal) + + var fv_trianglation:Array[int] = face.get_triangulation() + + for fv_idx in fv_trianglation: + + var v_idx:int = face.vertex_indices[fv_idx] + # var p:Vector3 = triangles[i] + var p:Vector3 = vertices[v_idx].point + + var uv:Vector2 + if axis == MathUtil.Axis.X: + uv = Vector2(-p.z, -p.y) + elif axis == MathUtil.Axis.Y: + uv = Vector2(-p.x, -p.z) + elif axis == MathUtil.Axis.Z: + uv = Vector2(-p.x, -p.y) + + uv = face.uv_transform * uv + uv1s.append(uv) + uv2s.append(face.lightmap_uvs[fv_idx]) + + normals.append(face.normal) + + points.append(p) + + var arrays:Array = [] + arrays.resize(Mesh.ARRAY_MAX) + arrays[Mesh.ARRAY_VERTEX] = points + arrays[Mesh.ARRAY_NORMAL] = normals + arrays[Mesh.ARRAY_TEX_UV] = uv1s + arrays[Mesh.ARRAY_TEX_UV2] = uv2s + + mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) + mesh.surface_set_material(surface_idx, material) + + var shadow_arrays:Array = [] + shadow_arrays.resize(Mesh.ARRAY_MAX) + shadow_arrays[Mesh.ARRAY_VERTEX] = points + + shadow_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, shadow_arrays) + shadow_mesh.surface_set_material(surface_idx, material) + + surface_idx += 1 + + mesh.shadow_mesh = shadow_mesh +# var err = mesh.lightmap_unwrap(Transform3D.IDENTITY, 10) +# print("Lightmap unwrap Error: %s" % err) + return mesh + + + +func append_mesh_backfacing(mesh:ImmediateMesh, material:Material, offset:float = .2): +# if Engine.is_editor_hint(): +# return + + for face in faces: + + mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLE_STRIP, material) +# print("face %s" % face.index) + + mesh.surface_set_normal(face.normal) + +# for i in tristrip_vertex_range_reverse(face.vertex_indices.size()): + for i in tristrip_vertex_range_reverse(face.vertex_indices.size()): + var v_idx:int = face.vertex_indices[i] + var v:VertexInfo = vertices[v_idx] + var p:Vector3 = v.point + v.normal * offset + #var p:Vector3 = v.point + Vector3(.1, .1, .1) + + mesh.surface_add_vertex(p) + + mesh.surface_end() + +func append_mesh_outline(mesh:ImmediateMesh, viewport_camera:Camera3D, local_to_world:Transform3D, material:Material, thickness:float = 4): +# var cam_dir:Vector3 = viewport_camera.global_transform.basis.z + var cam_orig:Vector3 = viewport_camera.global_transform.origin + +# print("append_mesh_outline %s" % cam_dir) + #points along Z +# var cylinder:GeometryMesh = MathGeometry.unit_cylinder(4, thickness, thickness, 0, -1) + + var segments:PackedVector2Array + + for edge in edges: + var has_front:bool = false + var has_back:bool = false + + for f_idx in edge.face_indices: + var face = faces[f_idx] + #print("face norm %s" % face.normal) + var point_on_plane:Vector3 = vertices[face.vertex_indices[0]].point + var to_plane:Vector3 = cam_orig - point_on_plane + + if face.normal.dot(to_plane) > 0: + has_front = true + elif face.normal.dot(to_plane) < 0: + has_back = true + + #print("front %s back %s" % [has_front, has_back]) + + if has_front && has_back: + #print("drawing edge %s %s" % [edge.start_index, edge.end_index]) + #Draw edge + var v0:VertexInfo = vertices[edge.start_index] + var v1:VertexInfo = vertices[edge.end_index] + var p0_world:Vector3 = local_to_world * v0.point + var p1_world:Vector3 = local_to_world * v1.point + var p0_screen:Vector2 = viewport_camera.unproject_position(p0_world) + var p1_screen:Vector2 = viewport_camera.unproject_position(p1_world) + segments.append(p0_screen) + segments.append(p1_screen) + + var loops:Array[PackedVector2Array] = MathUtil.get_loops_from_segments_2d(segments) + for loop_points in loops: + var out_dirs:PackedVector2Array + + for v_idx in loop_points.size(): + var p0_screen:Vector2 = loop_points[wrap(v_idx - 1, 0, loop_points.size())] + var p1_screen:Vector2 = loop_points[v_idx] + var p2_screen:Vector2 = loop_points[wrap(v_idx + + 1, 0, loop_points.size())] + #var span:Vector2 = p2_screen - p1_screen + + var norm01:Vector2 = (p1_screen - p0_screen).normalized() + var norm12:Vector2 = (p2_screen - p1_screen).normalized() + + var out_dir1:Vector2 = (-norm01 + norm12).normalized() + var perp:Vector2 = out_dir1 - out_dir1.project(norm12) + #Check winding + if perp.x * norm12.y - perp.y * norm12.x < 0: + out_dir1 = -out_dir1 + + out_dirs.append(out_dir1) + + + mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLE_STRIP, material) + for v_idx in loop_points.size() + 1: + var p_screen:Vector2 = loop_points[wrap(v_idx, 0, loop_points.size())] + var p_out_dir:Vector2 = out_dirs[wrap(v_idx, 0, loop_points.size())] + + var z_pos:float = (viewport_camera.near + viewport_camera.far) / 2 + var p0:Vector3 = viewport_camera.project_position(p_screen, z_pos) + var p1:Vector3 = viewport_camera.project_position(p_screen + p_out_dir * thickness, z_pos) + + mesh.surface_add_vertex(p0) + mesh.surface_add_vertex(p1) + + mesh.surface_end() + + + +func create_mesh_wire(material:Material)->ImmediateMesh: +# if Engine.is_editor_hint(): +# return + var mesh:ImmediateMesh = ImmediateMesh.new() + + mesh.surface_begin(Mesh.PRIMITIVE_LINES, material) + + for e in edges: + var v0:VertexInfo = vertices[e.start_index] + var v1:VertexInfo = vertices[e.end_index] + + mesh.surface_add_vertex(v0.point) + mesh.surface_add_vertex(v1.point) + + mesh.surface_end() + + return mesh + + +func intersect_ray_closest(origin:Vector3, dir:Vector3)->IntersectResults: + if bounds.intersects_ray(origin, dir) == null: + return null + + var best_result:IntersectResults + + for face in faces: +# var tris:PackedVector3Array = MathUtil.trianglate_face(face.get_points(), face.normal) + var tris:PackedVector3Array = face.get_trianges() + for i in range(0, tris.size(), 3): + var p0:Vector3 = tris[i] + var p1:Vector3 = tris[i + 1] + var p2:Vector3 = tris[i + 2] + + #Godot uses clockwise winding + var tri_area_x2:Vector3 = MathUtil.triangle_area_x2(p0, p1, p2) + + var p_hit:Vector3 = MathUtil.intersect_plane(origin, dir, p0, tri_area_x2) + if !p_hit.is_finite(): + continue + + if MathUtil.triangle_area_x2(p_hit, p0, p1).dot(tri_area_x2) < 0: + continue + if MathUtil.triangle_area_x2(p_hit, p1, p2).dot(tri_area_x2) < 0: + continue + if MathUtil.triangle_area_x2(p_hit, p2, p0).dot(tri_area_x2) < 0: + continue + + #Intersection + var dist_sq:float = (origin - p_hit).length_squared() + if !best_result || best_result.distance_squared > dist_sq: + + var result:IntersectResults = IntersectResults.new() + result.face_id = face.id + result.normal = face.normal + result.position = p_hit + result.distance_squared = dist_sq + + best_result = result + + return best_result + +func format_faces_string()->String: + var s:String = "" + for f in faces: + s = s + "[" + for v_idx in f.vertex_indices: + s += "%s, " % vertices[v_idx].point + s = s + "],\n" + return s + +func update_edge_and_face_selection_from_vertices(): + for e in edges: + e.selected = vertices[e.start_index].selected && vertices[e.end_index].selected + + for f in faces: + var all_sel:bool = true + for v_idx in f.vertex_indices: + if !vertices[v_idx].selected: + all_sel = false + break + f.selected = all_sel + + diff --git a/addons/cyclops_level_builder/math/face_packer.gd b/addons/cyclops_level_builder/math/face_packer.gd new file mode 100644 index 0000000..9a811ab --- /dev/null +++ b/addons/cyclops_level_builder/math/face_packer.gd @@ -0,0 +1,253 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends RefCounted +class_name FacePacker + +class SpawnResult extends RefCounted: + var point:Vector2 + var flip:bool + + func _init(point:Vector2, flip:bool): + self.point = point + self.flip = flip + +class FaceTree extends RefCounted: +# var root:FaceTreeNode + var size:Vector2 + var spawn_points:PackedVector2Array = [Vector2.ZERO] + var face_list:Array[FaceTracker] + var bounds:Rect2 + + func _to_string()->String: + var res:String = "" + for face in face_list: + res += "%s,\n" % str(face) + return res + + func is_collision(rect:Rect2)->bool: + for face in face_list: + if face.bounds.intersects(rect): + return true + return false + + func max_vec_dim(v:Vector2): + return max(v.x, v.y) + + func get_best_spawn_point(face:FaceTracker)->SpawnResult: + var started:bool = false + var best_spawn_point:Vector2 = Vector2.INF + var best_bounds:Rect2 + var best_flip:bool + + for s_idx in spawn_points.size(): + var spawn_point:Vector2 = spawn_points[s_idx] + + var placed_bounds:Rect2 = face.bounds + placed_bounds.position += spawn_point + + if !is_collision(placed_bounds): + var new_bounds:Rect2 = bounds.merge(placed_bounds) + + if new_bounds.is_equal_approx(bounds): + return SpawnResult.new(spawn_point, false) + else: + if !started || max_vec_dim(best_bounds.size) > max_vec_dim(new_bounds.size): + best_bounds = new_bounds + best_flip = false + best_spawn_point = spawn_point + started = true + + var placed_bounds_flipped:Rect2 = face.bounds + placed_bounds_flipped.size = Vector2(placed_bounds_flipped.size.y, placed_bounds_flipped.size.x) + placed_bounds_flipped.position += spawn_point + + if !is_collision(placed_bounds_flipped): + var new_bounds_flipped:Rect2 = bounds.merge(placed_bounds_flipped) + + if new_bounds_flipped.is_equal_approx(bounds): + return SpawnResult.new(spawn_point, true) + else: + if !started || max_vec_dim(best_bounds.size) > max_vec_dim(new_bounds_flipped.size): + best_bounds = new_bounds_flipped + best_flip = true + best_spawn_point = spawn_point + started = true + + return SpawnResult.new(best_spawn_point, best_flip) + + func add_face(face:FaceTracker): + var spawn:SpawnResult = get_best_spawn_point(face) + + var idx = spawn_points.find(spawn.point) + spawn_points.remove_at(idx) + + if spawn.flip: + face.reflect_diagonal() + + face.translate(spawn.point) + face_list.append(face) + bounds = bounds.merge(face.bounds) + + var sp_0:Vector2 = face.bounds.position + Vector2(face.bounds.size.x, 0) + var sp_1:Vector2 = face.bounds.position + Vector2(0, face.bounds.size.y) + if !spawn_points.has(sp_0): + spawn_points.append(sp_0) + if !spawn_points.has(sp_1): + spawn_points.append(sp_1) + + + +class FaceTracker extends RefCounted: + var points:PackedVector2Array + var indices:PackedInt32Array + var bounds:Rect2 + var face_index:int + + func _to_string()->String: + var res:String = "[" + for p in points: + res += "%s, " % str(p) + res += "]" + return res + + func max_dim()->float: + return max(bounds.size.x, bounds.size.y) + + func reflect_diagonal(): + for p_idx in points.size(): + var p:Vector2 = points[p_idx] + points[p_idx] = Vector2(p.y, p.x) + bounds.size = Vector2(bounds.size.y, bounds.size.x) + + func translate(offset:Vector2): + for p_idx in points.size(): + points[p_idx] += offset + bounds.position += offset + + func fit_initial_rect(): + bounds = Rect2(points[0], Vector2.ZERO) + for i in range(1, points.size()): + bounds = bounds.expand(points[i]) + + #Move so corner of bounds is at (0, 0) + for i in points.size(): + points[i] -= bounds.position + bounds.position = Vector2.ZERO + + func get_best_base_index()->int: + var best_index:int = -1 + var best_height:float = INF + + for i0 in points.size(): + var i1:int = wrap(i0 + 1, 0, points.size()) + + var base_dir:Vector2 = points[i1] - points[i0] + var base_origin:Vector2 = points[i0] + var base_dir_perp:Vector2 = Vector2(-base_dir.y, base_dir.x) + + var max_height:float = 0 + + for j in range(2, points.size()): + var p_idx:int = wrap(j + i0, 0, points.size()) + var p:Vector2 = points[p_idx] + var offset:Vector2 = p - base_origin + var offset_proj:Vector2 = offset.project(base_dir_perp) + + max_height = max(max_height, offset_proj.length_squared()) + + if max_height < best_height: + best_height = max_height + best_index = i0 + + return best_index + + func rotate_to_best_fit(): + var i0:int = get_best_base_index() + var i1:int = wrap(i0 + 1, 0, points.size()) + + var base_dir:Vector2 = (points[i1] - points[i0]).normalized() + var base_dir_perp:Vector2 = Vector2(-base_dir.y, base_dir.x) + + var xform:Transform2D = Transform2D(base_dir, base_dir_perp, Vector2.ZERO) + var xform_inv:Transform2D = xform.affine_inverse() + + for p_idx in points.size(): + var p:Vector2 = xform_inv * points[p_idx] + points[p_idx] = p + + +func pack_faces(faces:Array[FaceTracker])->FaceTree: + faces.sort_custom(func (a:FaceTracker, b:FaceTracker): return a.max_dim() > b.max_dim()) + + var tree:FaceTree = FaceTree.new() + for f in faces: + tree.add_face(f) + + #print(tree) + return tree + +func build_faces(vol:ConvexVolume, margin:float)->FaceTree: + var faces:Array[FaceTracker] + + for f_idx in vol.faces.size(): + var face:ConvexVolume.FaceInfo = vol.faces[f_idx] + var axis:MathUtil.Axis = MathUtil.get_longest_axis(face.normal) + + var cross_vec:Vector3 + if axis == MathUtil.Axis.Y: + cross_vec = Vector3.FORWARD + else: + cross_vec = Vector3.UP + + var u_axis:Vector3 = face.normal.cross(cross_vec) + var v_axis:Vector3 = u_axis.cross(face.normal) + var basis:Basis = Basis(u_axis, face.normal, v_axis) + + var xform:Transform3D = Transform3D(basis, face.get_centroid()) + var xz_xform:Transform3D = xform.affine_inverse() + + var tracker:FaceTracker = FaceTracker.new() + tracker.face_index = f_idx + faces.append(tracker) + + for v_idx in face.vertex_indices: + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + var proj:Vector3 = xz_xform * v.point + tracker.points.append(Vector2(proj.x, proj.z)) + tracker.indices.append(v_idx) + + #print("face init points %s" % tracker.points) + + tracker.rotate_to_best_fit() + #print("after rot %s" % tracker.points) + tracker.fit_initial_rect() + #print("after fit %s" % tracker.points) + for p_idx in tracker.points.size(): + tracker.points[p_idx] += Vector2(margin, margin) + tracker.bounds.size += Vector2(margin, margin) * 2 + + return pack_faces(faces) + + diff --git a/addons/cyclops_level_builder/math/general_mesh.gd b/addons/cyclops_level_builder/math/general_mesh.gd new file mode 100644 index 0000000..fff2bb4 --- /dev/null +++ b/addons/cyclops_level_builder/math/general_mesh.gd @@ -0,0 +1,447 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends RefCounted +class_name GeneralMesh + + +class VertexInfo extends RefCounted: + var index:int + var point:Vector3 + var edge_indices:Array[int] = [] + var selected:bool + + func _init(_index:int, _point:Vector3 = Vector3.ZERO): + index = _index + point = _point + + func _to_string(): + var s:String = "%s %s [" % [index, point] + for i in edge_indices: + s += "%s " % i + s += "]" + + return s + +class EdgeInfo extends RefCounted: + var index:int + var start_index:int + var end_index:int + var face_indices:Array[int] = [] + var selected:bool + + func _init(_index:int, _start:int = 0, _end:int = 0): + index = _index + start_index = _start + end_index = _end + + func _to_string(): + var s:String = "%s %s %s [" % [index, start_index, end_index] + for i in face_indices: + s += "%s " % i + s += "]" + return s + +class FaceInfo extends RefCounted: + var index:int + var normal:Vector3 +# var vertex_indices:Array[int] + var face_corner_indices:Array[int] + var material_index:int + var selected:bool + + func _init(_index:int, _face_corner_indices:Array[int] = [], _mat_index:int = 0): + index = _index + face_corner_indices = _face_corner_indices + material_index = _mat_index + + func _to_string(): + var s:String = "%s %s %s [" % [index, normal, material_index] + for i in face_corner_indices: + s += "%s " % i + s += "]" + return s + +class FaceCornerInfo extends RefCounted: + var index:int + var uv:Vector2 + var vertex_index:int + var face_index:int + var selected:bool + + func _init(_index:int, _vertex_index:int, _face_index:int): + vertex_index = _vertex_index + face_index = _face_index + + func _to_string(): + var s:String = "%s %s %s %s" % [index, uv, vertex_index, face_index] + return s + + + +var vertices:Array[VertexInfo] = [] +var edges:Array[EdgeInfo] = [] +var faces:Array[FaceInfo] = [] +var face_corners:Array[FaceCornerInfo] = [] +var bounds:AABB + +#var points:PackedVector3Array + +func _init(): +# init_block(Vector3.ZERO, Vector3.LEFT + Vector3.FORWARD, Vector3.UP) +# dump() + pass + +func get_face_indices()->PackedInt32Array: + var result:PackedInt32Array + for f in faces: + result.append(f.index) + return result + +func clear_lists(): + vertices = [] + edges = [] + faces = [] + face_corners = [] + bounds = AABB() + +func init_block(block_bounds:AABB): + var p000:Vector3 = block_bounds.position + var p111:Vector3 = block_bounds.end + var p001:Vector3 = Vector3(p000.x, p000.y, p111.z) + var p010:Vector3 = Vector3(p000.x, p111.y, p000.z) + var p011:Vector3 = Vector3(p000.x, p111.y, p111.z) + var p100:Vector3 = Vector3(p111.x, p000.y, p000.z) + var p101:Vector3 = Vector3(p111.x, p000.y, p111.z) + var p110:Vector3 = Vector3(p111.x, p111.y, p000.z) + + init_prism([p000, p001, p011, p010], p100 - p000) + + +func init_prism(base_points:Array[Vector3], extrude_dir:Vector3): + + var verts:PackedVector3Array + for p in base_points: + verts.append(p) + for p in base_points: + verts.append(p + extrude_dir) + + var index_list:PackedInt32Array + var face_len_list:PackedInt32Array + + var num_points:int = base_points.size() + for i0 in num_points: + var i1:int = wrap(i0 + 1, 0, num_points) + + index_list.append(i0) + index_list.append(i1) + index_list.append(i1 + num_points) + index_list.append(i0 + num_points) + face_len_list.append(4) + + for i0 in num_points: +# index_list.append(i0) + index_list.append(num_points - i0 - 1) + face_len_list.append(num_points) + + for i0 in num_points: + index_list.append(i0 + num_points) +# index_list.append(num_points * 2 - i0 - 1) + face_len_list.append(num_points) + + init_from_face_lists(verts, index_list, face_len_list) + + +func init_from_face_lists(verts:PackedVector3Array, index_list:PackedInt32Array, face_len_list:PackedInt32Array): + clear_lists() + + for i in verts.size(): + var v:VertexInfo = VertexInfo.new(i, verts[i]) + vertices.append(v) + + if i == 0: + bounds = AABB(verts[0], Vector3.ZERO) + else: + bounds = bounds.expand(verts[i]) + + var vertex_index_offset:int = 0 + for face_index in face_len_list.size(): + var num_face_verts = face_len_list[face_index] +# if num_face_verts < 3: +# continue + + var face_corners_local:Array[int] = [] + for i in num_face_verts: + var face_corner_index:int = face_corners.size() + var face_corner:FaceCornerInfo = FaceCornerInfo.new(face_corner_index, index_list[vertex_index_offset], face_index) + face_corners.append(face_corner) + face_corners_local.append(face_corner_index) + vertex_index_offset += 1 + + var face:FaceInfo = FaceInfo.new(face_index, face_corners_local) + faces.append(face) + + #Calc normal + var fc0:FaceCornerInfo = face_corners[face_corners_local[0]] +# var vidx0 = fc0.vertex_index + var p0:Vector3 = vertices[fc0.vertex_index].point +# + var weighted_normal:Vector3 + for i in range(1, num_face_verts - 1): + var fc1:FaceCornerInfo = face_corners[face_corners_local[i]] + var fc2:FaceCornerInfo = face_corners[face_corners_local[i + 1]] +# var vidx1 = fc1.vertex_index +# var vidx2 = fc2.vertex_index + var p1:Vector3 = vertices[fc1.vertex_index].point + var p2:Vector3 = vertices[fc2.vertex_index].point + + var v1:Vector3 = p1 - p0 + var v2:Vector3 = p2 - p0 + weighted_normal += v2.cross(v1) + + face.normal = weighted_normal.normalized() + + #Calculate edges + for face in faces: + var num_corners = face.face_corner_indices.size() + for i0 in num_corners: + var i1:int = wrap(i0 + 1, 0, num_corners) + var fc0:FaceCornerInfo = face_corners[face.face_corner_indices[i0]] + var fc1:FaceCornerInfo = face_corners[face.face_corner_indices[i1]] + + var edge:EdgeInfo = get_edge(fc0.vertex_index, fc1.vertex_index) + if !edge: + var edge_idx = edges.size() + edge = EdgeInfo.new(edge_idx, fc0.vertex_index, fc1.vertex_index) + edges.append(edge) + + var v0:VertexInfo = vertices[fc0.vertex_index] + v0.edge_indices.append(edge_idx) + + var v1:VertexInfo = vertices[fc1.vertex_index] + v1.edge_indices.append(edge_idx) + + edge.face_indices.append(face.index) + + +func get_edge(vert_idx0:int, vert_idx1:int)->EdgeInfo: + for e in edges: + if e.start_index == vert_idx0 && e.end_index == vert_idx1: + return e + if e.start_index == vert_idx1 && e.end_index == vert_idx0: + return e + return null + + +func init_block_data(block:BlockData): + clear_lists() + + for i in block.points.size(): + var v:VertexInfo = VertexInfo.new(i, block.points[i]) + vertices.append(v) + + if i == 0: + bounds = AABB(v.point, Vector3.ZERO) + else: + bounds = bounds.expand(v.point) + + var corner_index_offset:int = 0 + for face_index in block.face_vertex_count.size(): + var num_face_verts = block.face_vertex_count[face_index] + + var face_corners_local:Array[int] = [] + for i in num_face_verts: + var vertex_index = block.face_vertex_indices[corner_index_offset] + + var face_corner:FaceCornerInfo = FaceCornerInfo.new(corner_index_offset, vertex_index, face_index) + face_corner.uv = block.uvs[corner_index_offset] + face_corners.append(face_corner) + face_corners_local.append(corner_index_offset) + corner_index_offset += 1 + + var face:FaceInfo = FaceInfo.new(face_index, face_corners_local) + face.material_index = block.face_material_indices[face_index] + faces.append(face) + + #Calc normal + var fc0:FaceCornerInfo = face_corners[face_corners_local[0]] + var p0:Vector3 = vertices[fc0.vertex_index].point +# + var weighted_normal:Vector3 + for i in range(1, num_face_verts - 1): + var fc1:FaceCornerInfo = face_corners[face_corners_local[i]] + var fc2:FaceCornerInfo = face_corners[face_corners_local[i + 1]] + var p1:Vector3 = vertices[fc1.vertex_index].point + var p2:Vector3 = vertices[fc2.vertex_index].point + + var v1:Vector3 = p1 - p0 + var v2:Vector3 = p2 - p0 + weighted_normal += v2.cross(v1) + + face.normal = weighted_normal.normalized() + + #Calculate edges + for face in faces: + var num_corners = face.face_corner_indices.size() + for i0 in num_corners: + var i1:int = wrap(i0 + 1, 0, num_corners) + var fc0:FaceCornerInfo = face_corners[face.face_corner_indices[i0]] + var fc1:FaceCornerInfo = face_corners[face.face_corner_indices[i1]] + + var edge:EdgeInfo = get_edge(fc0.vertex_index, fc1.vertex_index) + if !edge: + var edge_idx = edges.size() + edge = EdgeInfo.new(edge_idx, fc0.vertex_index, fc1.vertex_index) + edges.append(edge) + + var v0:VertexInfo = vertices[fc0.vertex_index] + v0.edge_indices.append(edge_idx) + + var v1:VertexInfo = vertices[fc1.vertex_index] + v1.edge_indices.append(edge_idx) + + edge.face_indices.append(face.index) + + +func to_block_data()->BlockData: + var block:BlockData = preload("res://addons/cyclops_level_builder/resources/block_data.gd").new() +# var block:BlockData = BlockData.new() + + for v in vertices: + block.points.append(v.point) + + for f in faces: + block.face_vertex_count.append(f.face_corner_indices.size()) + block.face_material_indices.append(f.material_index) + + for fc_idx in f.face_corner_indices: + var fc:FaceCornerInfo = face_corners[fc_idx] + block.face_vertex_indices.append(fc.vertex_index) + block.uvs.append(fc.uv) + + return block + +func append_mesh(mesh:ImmediateMesh, material:Material, color:Color = Color.WHITE): + + for face in faces: + mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLE_STRIP, material) +# print("face %s" % face.index) + + mesh.surface_set_normal(face.normal) + + var num_corners:int = face.face_corner_indices.size() + for i in num_corners: + var idx = (i + 1) / 2 if i & 1 else wrap(num_corners - (i / 2), 0, num_corners) + var fc:FaceCornerInfo = face_corners[face.face_corner_indices[idx]] + + mesh.surface_set_color(color) + mesh.surface_set_uv(fc.uv) + mesh.surface_add_vertex(vertices[fc.vertex_index].point) +# print ("%s %s %s" % [idx, fc.vertex_index, control_mesh.vertices[fc.vertex_index].point]) + + mesh.surface_end() + +func triplanar_unwrap(scale:float = 1): + for fc in face_corners: + var v:VertexInfo = vertices[fc.vertex_index] + var f:FaceInfo = faces[fc.face_index] + + if abs(f.normal.x) > abs(f.normal.y) && abs(f.normal.x) > abs(f.normal.z): + fc.uv = Vector2(v.point.y, v.point.z) * scale + elif abs(f.normal.y) > abs(f.normal.z): + fc.uv = Vector2(v.point.x, v.point.z) * scale + else: + fc.uv = Vector2(v.point.x, v.point.y) * scale + + +func get_face_points(face:FaceInfo)->PackedVector3Array: + var points:PackedVector3Array + for fc_idx in face.face_corner_indices: + var fc:FaceCornerInfo = face_corners[fc_idx] + points.append(vertices[fc.vertex_index].point) + return points + +func triangulate_face(face:FaceInfo)->PackedVector3Array: + var points:PackedVector3Array = get_face_points(face) + return MathUtil.trianglate_face(points, face.normal) + + +func intersect_ray_closest(origin:Vector3, dir:Vector3)->IntersectResults: + if bounds.intersects_ray(origin, dir) == null: + return null + + var best_result:IntersectResults + + for f in faces: + var tris:PackedVector3Array = triangulate_face(f) + for i in range(0, tris.size(), 3): + var p0:Vector3 = tris[i] + var p1:Vector3 = tris[i + 1] + var p2:Vector3 = tris[i + 2] + + #Godot uses clockwise winding + var tri_area_x2:Vector3 = MathUtil.triangle_area_x2(p0, p1, p2) + + var p_hit:Vector3 = MathUtil.intersect_plane(origin, dir, p0, tri_area_x2) + if !p_hit.is_finite(): + continue + + if MathUtil.triangle_area_x2(p_hit, p0, p1).dot(tri_area_x2) < 0: + continue + if MathUtil.triangle_area_x2(p_hit, p1, p2).dot(tri_area_x2) < 0: + continue + if MathUtil.triangle_area_x2(p_hit, p2, p0).dot(tri_area_x2) < 0: + continue + + #Intersection + var dist_sq:float = (origin - p_hit).length_squared() + if !best_result || best_result.distance_squared > dist_sq: + + var result:IntersectResults = IntersectResults.new() + result.face_index = f.index + result.normal = f.normal + result.position = p_hit + result.distance_squared = dist_sq + + best_result = result + + return best_result + +func translate(offset:Vector3): + for v in vertices: + v.point += offset + +func dump(): + print ("Verts") + for v in vertices: + print(v.to_string()) + print ("Edges") + for e in edges: + print(e.to_string()) + print ("Faces") + for f in faces: + print(f.to_string()) + print ("Face Corners") + for f in face_corners: + print(f.to_string()) diff --git a/addons/cyclops_level_builder/math/geometry_mesh.gd b/addons/cyclops_level_builder/math/geometry_mesh.gd new file mode 100644 index 0000000..7d96ffe --- /dev/null +++ b/addons/cyclops_level_builder/math/geometry_mesh.gd @@ -0,0 +1,63 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +#extends RefCounted +class_name GeometryMesh + +var coords:PackedVector3Array +var normals:PackedVector3Array +var uvs:PackedVector2Array + +func transform(xform:Transform3D)->GeometryMesh: + var result:GeometryMesh = GeometryMesh.new() + + var basis:Basis = xform.basis + basis = basis.inverse() + basis = basis.transposed() + + for i in coords.size(): + result.coords.append(xform * coords[i]) + result.uvs.append(uvs[i]) + result.normals.append(basis * normals[i]) + + return result + +func append_to_immediate_mesh(mesh:ImmediateMesh, material:Material, xform:Transform3D = Transform3D.IDENTITY): + mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLES, material) + + var basis:Basis = xform.basis + basis = basis.inverse() + basis = basis.transposed() + + for i in coords.size(): + var normal:Vector3 = basis * normals[i] + var coord:Vector3 = xform * coords[i] + var uv:Vector2 = uvs[i] + + mesh.surface_set_normal(normal) + mesh.surface_set_uv(uv) + mesh.surface_add_vertex(coord) + + mesh.surface_end() + diff --git a/addons/cyclops_level_builder/math/math_geometry.gd b/addons/cyclops_level_builder/math/math_geometry.gd new file mode 100644 index 0000000..68c0c64 --- /dev/null +++ b/addons/cyclops_level_builder/math/math_geometry.gd @@ -0,0 +1,166 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +#extends RefCounted +class_name MathGeometry + + +static func unit_cylinder(segs:int = 16, radius0:float = 1, radius1:float = 1, top_height:float = 1, bottom_height:float = -1, bottom_cap:bool = false, top_cap:bool = false)->GeometryMesh: + var mesh:GeometryMesh = GeometryMesh.new() + + + var vc0:Vector3 = Vector3(0, 0, -1) + var vc1:Vector3 = Vector3(0, 0, 1) + var uvc:Vector2 = Vector2(.5, .5) + + for s in range(segs): + + var sin0:float = sin(deg_to_rad(360 * s / segs)) + var cos0:float = cos(deg_to_rad(360 * s / segs)) + var sin1:float = sin(deg_to_rad(360 * (s + 1) / segs)) + var cos1:float = cos(deg_to_rad(360 * (s + 1) / segs)) + + var v00:Vector3 = Vector3(sin0 * radius0, cos0 * radius0, bottom_height) + var v10:Vector3 = Vector3(sin1 * radius0, cos1 * radius0, bottom_height) + var v01:Vector3 = Vector3(sin0 * radius1, cos0 * radius1, top_height) + var v11:Vector3 = Vector3(sin1 * radius1, cos1 * radius1, top_height) + + var tan0:Vector3 = Vector3(cos0, sin0, 0) + var n00:Vector3 = (v01 - v00).cross(tan0) + n00 = n00.normalized() + var n01:Vector3 = n00 + var tan1:Vector3 = Vector3(cos1, sin1, 0) + var n10:Vector3 = (v11 - v10).cross(tan1) + n10 = n10.normalized() + var n11 = n10 + + var uv00:Vector2 = Vector2(s / segs, 0) + var uv10:Vector2 = Vector2((s + 1) / segs, 0) + var uv01:Vector2 = Vector2(s / segs, 1) + var uv11:Vector2 = Vector2((s + 1) / segs, 1) + + if radius0 != 0: + mesh.coords.append(v00) + mesh.coords.append(v10) + mesh.coords.append(v11) + + mesh.normals.append(n00) + mesh.normals.append(n10) + mesh.normals.append(n11) + + mesh.uvs.append(uv00) + mesh.uvs.append(uv10) + mesh.uvs.append(uv11) + + if radius1 != 0: + mesh.coords.append(v00) + mesh.coords.append(v11) + mesh.coords.append(v01) + + mesh.normals.append(n00) + mesh.normals.append(n11) + mesh.normals.append(n01) + + mesh.uvs.append(uv00) + mesh.uvs.append(uv11) + mesh.uvs.append(uv01) + + if top_cap and radius1 != 0: + mesh.coords.append(v01) + mesh.coords.append(v11) + mesh.coords.append(vc1) + + mesh.normals.append(Vector3(0, 0, 1)) + mesh.normals.append(Vector3(0, 0, 1)) + mesh.normals.append(Vector3(0, 0, 1)) + + mesh.uvs.append(Vector2(sin0, cos0)) + mesh.uvs.append(Vector2(sin1, cos1)) + mesh.uvs.append(uvc) + + if bottom_cap and radius0 != 0: + mesh.coords.append(v00) + mesh.coords.append(v10) + mesh.coords.append(vc0) + + mesh.normals.append(-Vector3(0, 0, 1)) + mesh.normals.append(-Vector3(0, 0, 1)) + mesh.normals.append(-Vector3(0, 0, 1)) + + mesh.uvs.append(Vector2(sin0, cos0)) + mesh.uvs.append(Vector2(sin1, cos1)) + mesh.uvs.append(uvc) + + + return mesh + +static func unit_sphere(segs_lat:int = 6, segs_long:int = 8)->GeometryMesh: + var mesh:GeometryMesh = GeometryMesh.new() + + for la in range(segs_lat): + + var z0:float = cos(deg_to_rad(180 * la / segs_lat)) + var z1:float = cos(deg_to_rad(180 * (la + 1) / segs_lat)) + var r0:float = sin(deg_to_rad(180 * la / segs_lat)) + var r1:float = sin(deg_to_rad(180 * (la + 1) / segs_lat)) + + for lo in range(segs_long): + var cx0:float = sin(deg_to_rad(360 * lo / segs_long)) + var cx1:float = sin(deg_to_rad(360 * (lo + 1) / segs_long)) + var cy0:float = cos(deg_to_rad(360 * lo / segs_long)) + var cy1:float = cos(deg_to_rad(360 * (lo + 1) / segs_long)) + + var v00:Vector3 = Vector3(cx0 * r0, cy0 * r0, z0) + var v10:Vector3 = Vector3(cx1 * r0, cy1 * r0, z0) + var v01:Vector3 = Vector3(cx0 * r1, cy0 * r1, z1) + var v11:Vector3 = Vector3(cx1 * r1, cy1 * r1, z1) + + if la != 0: + mesh.coords.append(v00) + mesh.coords.append(v11) + mesh.coords.append(v10) + + mesh.normals.append(v00) + mesh.normals.append(v10) + mesh.normals.append(v10) + + mesh.uvs.append(Vector2(lo / segs_long, la / segs_lat)) + mesh.uvs.append(Vector2((lo + 1) / segs_long, la / segs_lat)) + mesh.uvs.append(Vector2((lo + 1) / segs_long, (la + 1) / segs_lat)) + + if la != segs_lat - 1: + mesh.coords.append(v00) + mesh.coords.append(v01) + mesh.coords.append(v11) + + mesh.normals.append(v00) + mesh.normals.append(v01) + mesh.normals.append(v11) + + mesh.uvs.append(Vector2(lo / segs_long, la / segs_lat)) + mesh.uvs.append(Vector2((lo + 1) / segs_long, (la + 1) / segs_lat)) + mesh.uvs.append(Vector2(lo / segs_long, (la + 1) / segs_lat)) + + return mesh + diff --git a/addons/cyclops_level_builder/math/math_util.gd b/addons/cyclops_level_builder/math/math_util.gd new file mode 100644 index 0000000..b6c2e8a --- /dev/null +++ b/addons/cyclops_level_builder/math/math_util.gd @@ -0,0 +1,537 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name MathUtil + +enum Axis { X, Y, Z } + +static func square(value:float)->float: + return value * value + +static func snap_to_grid(pos:Vector3, cell_size:float)->Vector3: +# return floor(pos / cell_size) * cell_size + return floor((pos + Vector3(cell_size, cell_size, cell_size) / 2) / cell_size) * cell_size + + +#Returns intersection of line with point. +# plane_perp_dir points in direction of plane's normal and does not need to be normalized +static func intersect_plane(ray_origin:Vector3, ray_dir:Vector3, plane_origin:Vector3, plane_perp_dir:Vector3)->Vector3: + var s:float = (plane_origin - ray_origin).dot(plane_perp_dir) / ray_dir.dot(plane_perp_dir) + return ray_origin + ray_dir * s + +#Returns the closest point on the line to the ray +static func closest_point_on_line(ray_origin:Vector3, ray_dir:Vector3, line_origin:Vector3, line_dir:Vector3)->Vector3: + var a:Vector3 = ray_dir.cross(line_dir) + var w_perp:Vector3 = ray_dir.cross(a) + return intersect_plane(line_origin, line_dir, ray_origin, w_perp) + +static func closest_point_on_segment(ray_origin:Vector3, ray_dir:Vector3, seg_start:Vector3, seg_end:Vector3)->Vector3: + var seg_span:Vector3 = seg_end - seg_start + var p:Vector3 = closest_point_on_line(ray_origin, ray_dir, seg_start, seg_span) + var offset:Vector3 = p - seg_start + if offset.dot(seg_span) < 0: + return seg_start + if offset.length_squared() > seg_span.length_squared(): + return seg_end + return p + +#Shortest distance from point to given ray. Returns NAN if point is behind origin of ray. +static func distance_to_ray(ray_origin:Vector3, ray_dir:Vector3, point:Vector3): + var offset = point - ray_origin + var parallel:Vector3 = offset.project(ray_dir) + if parallel.dot(ray_dir) < 0: + return NAN + + var perp:Vector3 = offset - parallel + return perp.length() + + +static func trianglate_face(points:PackedVector3Array, normal:Vector3)->PackedVector3Array: + var result:PackedVector3Array + + while (points.size() >= 3): + var num_points:int = points.size() + for i in range(0, num_points): + var p0:Vector3 = points[i] + var p1:Vector3 = points[wrap(i + 1, 0, num_points)] + var p2:Vector3 = points[wrap(i + 2, 0, num_points)] + + #Godot uses clockwise winding + var tri_norm_dir:Vector3 = (p2 - p0).cross(p1 - p0) + if tri_norm_dir.dot(normal) > 0: + result.append(p0) + result.append(p1) + result.append(p2) + + points.remove_at(i + 1) + break + + return result + +static func trianglate_face_indices(points:PackedVector3Array, indices:Array[int], normal:Vector3)->Array[int]: + var result:Array[int] = [] + +# print("trianglate_face_indices %s" % points) + + while (points.size() >= 3): + var num_points:int = points.size() + var added_point:bool = false + + for i in range(0, num_points): + var idx0:int = i + var idx1:int = wrap(i + 1, 0, num_points) + var idx2:int = wrap(i + 2, 0, num_points) + var p0:Vector3 = points[idx0] + var p1:Vector3 = points[idx1] + var p2:Vector3 = points[idx2] + + #Godot uses clockwise winding + var tri_norm_dir:Vector3 = (p2 - p0).cross(p1 - p0) + if tri_norm_dir.dot(normal) > 0: + result.append(indices[idx0]) + result.append(indices[idx1]) + result.append(indices[idx2]) + +# print("adding indices %s %s %s" % [indices[idx0], indices[idx1], indices[idx2]]) + + points.remove_at(idx1) + indices.remove_at(idx1) + added_point = true + break + + assert(added_point, "failed to add point in triangulation") +# print("tri_done %s" % str(result)) + + return result + +static func trianglate_face_vertex_indices(points:PackedVector3Array, normal:Vector3)->Array[int]: + var result:Array[int] = [] + var fv_indices:Array = range(0, points.size()) +# print("trianglate_face_indices %s" % points) + + while (points.size() >= 3): + var num_points:int = points.size() + var added_point:bool = false + + for i in range(0, num_points): + var idx0:int = i + var idx1:int = wrap(i + 1, 0, num_points) + var idx2:int = wrap(i + 2, 0, num_points) + var p0:Vector3 = points[idx0] + var p1:Vector3 = points[idx1] + var p2:Vector3 = points[idx2] + + #Godot uses clockwise winding + var tri_norm_dir:Vector3 = (p2 - p0).cross(p1 - p0) + if tri_norm_dir.dot(normal) > 0: + result.append(fv_indices[idx0]) + result.append(fv_indices[idx1]) + result.append(fv_indices[idx2]) + +# print("adding indices %s %s %s" % [indices[idx0], indices[idx1], indices[idx2]]) + + points.remove_at(idx1) + fv_indices.remove_at(idx1) + added_point = true + break + + assert(added_point, "failed to add point in triangulation") +# print("tri_done %s" % str(result)) + + return result + +static func flip_plane(plane:Plane)->Plane: + return Plane(-plane.normal, plane.get_center()) + +#Returns a vector pointing along the normal in the clockwise winding direction with a length equal to twice the area of the triangle +static func triangle_area_x2(p0:Vector3, p1:Vector3, p2:Vector3)->Vector3: + return (p2 - p0).cross(p1 - p0) + +#Returns a vector pointing along the normal in the clockwise winding direction with a lengh equal to twice the area of the face +static func face_area_x2(points:PackedVector3Array)->Vector3: + if points.size() <= 1: + return Vector3.ZERO + + var result:Vector3 + var p0:Vector3 = points[0] + + for i in range(1, points.size() - 1): + var p1:Vector3 = points[i] + var p2:Vector3 = points[i + 1] + + result += (p2 - p0).cross(p1 - p0) + + return result + +static func face_area_x2_2d(points:PackedVector2Array)->float: + if points.size() <= 1: + return 0 + + var result:float + var p0:Vector2 = points[0] + + for i in range(1, points.size() - 1): + var p1:Vector2 = points[i] + var p2:Vector2 = points[i + 1] + + result += triange_area_2x_2d(p1 - p0, p2 - p0) + + return result + +static func fit_plane(points:PackedVector3Array)->Plane: + var normal:Vector3 = face_area_x2(points).normalized() + return Plane(normal, points[0]) + +static func snap_to_best_axis_normal(vector:Vector3)->Vector3: + if abs(vector.x) > abs(vector.y) and abs(vector.x) > abs(vector.z): + return Vector3(1, 0, 0) if vector.x > 0 else Vector3(-1, 0, 0) + elif abs(vector.y) > abs(vector.z): + return Vector3(0, 1, 0) if vector.y > 0 else Vector3(0, -1, 0) + else: + return Vector3(0, 0, 1) if vector.z > 0 else Vector3(0, 0, -1) + +static func get_longest_axis(vector:Vector3)->Axis: + if abs(vector.x) > abs(vector.y) and abs(vector.x) > abs(vector.z): + return Axis.X + elif abs(vector.y) > abs(vector.z): + return Axis.Y + else: + return Axis.Z + +static func calc_bounds(points:PackedVector3Array)->AABB: + if points.is_empty(): + return AABB(Vector3.ZERO, Vector3.ZERO) + + var result:AABB = AABB(points[0], Vector3.ZERO) + for i in range(1, points.size()): + result = result.expand(points[i]) + return result + +#Returns value equal to twise the area between the two vectors. Clockwise windings have negative area +static func triange_area_2x_2d(a:Vector2, b:Vector2)->float: + return a.x * b.y - a.y * b.x + +#Finds the bouding polygons of this set of points with a clockwise winding +static func bounding_polygon_2d(base_points:PackedVector2Array)->PackedVector2Array: + if base_points.size() <= 2: + return base_points + + + #Start with leftmost vertex, topmost if more than one + var p_init:Vector2 = base_points[0] + for p in base_points: + if p.x < p_init.x or (p.x == p_init.x and p.y > p_init.y): + p_init = p + + + var p_cur:Vector2 = p_init + var last_segment_dir = Vector2(0, 1) + + var polygon:PackedVector2Array + + while true: + var best_point:Vector2 + var best_dir:Vector2 + var best_angle:float = 0 + + for p in base_points: + if p.is_equal_approx(p_cur): + continue + + var point_dir:Vector2 = (p - p_cur).normalized() + var angle:float = acos(-last_segment_dir.dot(point_dir)) + + if angle > best_angle or (angle == best_angle and p_cur.distance_squared_to(p) > p_cur.distance_squared_to(best_point)): + best_point = p + best_dir = point_dir + best_angle = angle + + p_cur = best_point + last_segment_dir = best_dir + polygon.append(best_point) + + if best_point.is_equal_approx(p_init): + break + + return polygon + +#static func bounding_polygon(base_points:PackedVector3Array, plane:Plane)->PackedVector3Array: +static func bounding_polygon_3d(base_points:PackedVector3Array, normal:Vector3)->PackedVector3Array: + if base_points.size() <= 2: + return base_points + + var quat:Quaternion = Quaternion(normal, Vector3.FORWARD) + +# var xform:Transform3D = Transform3D(Basis(quat), -base_points[0]) + var xform:Transform3D = Transform3D(Basis(quat)) + xform = xform.translated_local(-base_points[0]) + var xform_inv = xform.inverse() + + #print("xform %s" % xform) + + var points_local:PackedVector2Array + + for p in base_points: + var p_local = xform * p + points_local.append(Vector2(p_local.x, p_local.y)) + + var points_bounds:PackedVector2Array = bounding_polygon_2d(points_local) + + var result:PackedVector3Array + for p in points_bounds: + var p_result = xform_inv * Vector3(p.x, p.y, 0) + result.append(p_result) + + return result + +static func points_are_colinear(points:PackedVector3Array)->bool: + if points.size() <= 2: + return true + + var p0:Vector3 = points[0] + var p1:Vector3 = p0 + var index:int = 0 + for i in range(1, points.size()): + if !points[i].is_equal_approx(p0): + p1 = points[i] + index = i + break + + if index == 0: + return true + + var v10:Vector3 = p1 - p0 + for i in range(index + 1, points.size()): + if !triangle_area_x2(p0, p1, points[i]).is_zero_approx(): + return false + + return true + + +static func furthest_point_from_line(line_origin:Vector3, line_dir:Vector3, points:PackedVector3Array)->Vector3: + var best_point:Vector3 + var best_dist:float = 0 + + for p in points: + var offset:Vector3 = p - line_origin + var along:Vector3 = offset.project(line_dir) + var perp:Vector3 = offset - along + var dist:float = perp.length_squared() + if dist > best_dist: + best_dist = dist + best_point = p + + return best_point + +static func furthest_point_from_plane(plane:Plane, points:PackedVector3Array)->Vector3: + var best_point:Vector3 + var best_distance:float = 0 + + for p in points: + var dist = abs(plane.distance_to(p)) + if dist > best_distance: + best_point = p + best_distance = dist + + return best_point + +static func planar_volume_contains_point(planes:Array[Plane], point:Vector3)->bool: +# print("candidate %s" % point) + + for p in planes: + var is_over:bool = p.is_point_over(point) + var is_on:bool = p.has_point(point) + if !is_over && !is_on: +# print("reject by %s" % p) + return false +# print("passed %s" % point) + return true + +static func get_convex_hull_points_from_planes(planes:Array[Plane])->Array[Vector3]: + #Check for overlapping planes + for i0 in range(0, planes.size()): + for i1 in range(i0 + 1, planes.size()): + var p0:Plane = planes[i0] + var p1:Plane = flip_plane(planes[i1]) + if p0.is_equal_approx(p1): + return [] + + var points:Array[Vector3] + + for i0 in range(0, planes.size()): + for i1 in range(i0 + 1, planes.size()): + for i2 in range(i1 + 1, planes.size()): + var result = planes[i0].intersect_3(planes[i1], planes[i2]) + + if result == null: + continue + #print("candidate %s" % result) + if !planar_volume_contains_point(planes, result): + continue + if points.any(func(p):return p.is_equal_approx(result)): + continue + #print("adding %s" % result) + points.append(result) + + return points + +static func dist_to_segment_squared_2d(point:Vector2, seg_start:Vector2, seg_end:Vector2)->float: + var dist_sq_p0:float = point.distance_squared_to(seg_start) + var dist_sq_p1:float = point.distance_squared_to(seg_end) + var seg_span:Vector2 = seg_end - seg_start + + var offset:Vector2 = point - seg_start + var offset_proj:Vector2 = offset.project(seg_span) + var perp_dist_sq:float = (offset - offset_proj).length_squared() + + if seg_span.dot(offset) < 0: + return dist_sq_p0 + elif offset_proj.length_squared() > seg_span.length_squared(): + return dist_sq_p1 + return perp_dist_sq + +class Segment2d extends RefCounted: + var p0:Vector2 + var p1:Vector2 + + func _init(p0:Vector2, p1:Vector2): + self.p0 = p0 + self.p1 = p1 + + func reverse()->Segment2d: + return Segment2d.new(p1, p0) + + func _to_string(): + return "[%s %s]" % [p0, p1] + +static func extract_loop_2d(seg_stack:Array[Segment2d])->PackedVector2Array: + var segs_sorted:Array[Segment2d] = [] + var prev_seg = seg_stack.pop_back() + segs_sorted.append(prev_seg) + + while !seg_stack.is_empty(): + var found_seg:bool = false + for s_idx in seg_stack.size(): + var cur_seg:Segment2d = seg_stack[s_idx] + + if cur_seg.p0.is_equal_approx(prev_seg.p1): +# print("matching %s with %s" % [prev_seg, cur_seg]) + segs_sorted.append(cur_seg) + seg_stack.remove_at(s_idx) + prev_seg = cur_seg + found_seg = true + break + elif cur_seg.p1.is_equal_approx(prev_seg.p1): +# print("matching %s with %s" % [prev_seg, cur_seg]) + cur_seg = cur_seg.reverse() + segs_sorted.append(cur_seg) + seg_stack.remove_at(s_idx) + prev_seg = cur_seg + found_seg = true + break + + if !found_seg: +# push_warning("loop not continuous") + break + +# print("segs_sorted %s" % str(segs_sorted)) + + var result:PackedVector2Array + for s in segs_sorted: + result.append(s.p0) + + if face_area_x2_2d(result) < 0: + result.reverse() + + return result + +static func get_loops_from_segments_2d(segments:PackedVector2Array)->Array[PackedVector2Array]: + #print("segments %s" % segments) + var loops:Array[PackedVector2Array] = [] + + var seg_stack:Array[Segment2d] = [] + for i in range(0, segments.size(), 2): + seg_stack.append(Segment2d.new(segments[i], segments[i + 1])) + +# print("segs %s" % str(seg_stack)) + + while !seg_stack.is_empty(): + var loop:PackedVector2Array = extract_loop_2d(seg_stack) + loops.append(loop) + +# print("result %s" % str(result)) + return loops + +static func create_transform(translation:Vector3, rotation_axis:Vector3, rotation_angle:float, scale:Vector3, pivot:Vector3)->Transform3D: + var xform:Transform3D = Transform3D.IDENTITY + + xform = xform.translated_local(pivot + translation) + xform = xform.rotated_local(rotation_axis, rotation_angle) + xform = xform.scaled_local(scale) + xform = xform.translated_local(-pivot) + + return xform + +static func create_circle_points(center:Vector3, normal:Vector3, radius:float, num_segments:int)->PackedVector3Array: + var result:PackedVector3Array + + var axis:Axis = get_longest_axis(normal) + var perp_normal:Vector3 + match axis: + Axis.X: + perp_normal = normal.cross(Vector3.UP) + Axis.Y: + perp_normal = normal.cross(Vector3.FORWARD) + Axis.Z: + perp_normal = normal.cross(Vector3.UP) + + var angle_incrment = (PI * 2 / num_segments) + for i in num_segments: + var offset:Vector3 = perp_normal.rotated(normal, i * angle_incrment) + result.append(offset * radius + center) + + return result + +static func get_axis_aligned_tangent_and_binormal(normal:Vector3)->Array[Vector3]: + var axis:MathUtil.Axis = MathUtil.get_longest_axis(normal) + #calc tangent and binormal + var u_normal:Vector3 + var v_normal:Vector3 + match axis: + MathUtil.Axis.Y: + u_normal = normal.cross(Vector3.FORWARD) + v_normal = u_normal.cross(normal) + return [u_normal, v_normal] + MathUtil.Axis.X: + u_normal = normal.cross(Vector3.UP) + v_normal = u_normal.cross(normal) + return [u_normal, v_normal] + MathUtil.Axis.Z: + u_normal = normal.cross(Vector3.UP) + v_normal = u_normal.cross(normal) + return [u_normal, v_normal] + + return [] + + diff --git a/addons/cyclops_level_builder/math/quick_hull.gd b/addons/cyclops_level_builder/math/quick_hull.gd new file mode 100644 index 0000000..fc08316 --- /dev/null +++ b/addons/cyclops_level_builder/math/quick_hull.gd @@ -0,0 +1,360 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends RefCounted +class_name QuickHull + +class DirectedEdge extends RefCounted: + var p0:Vector3 + var p1:Vector3 + + func _init(p0:Vector3, p1:Vector3): + self.p0 = p0 + self.p1 = p1 + + func _to_string()->String: + return "%s %s" % [p0, p1] + + func reverse()->DirectedEdge: + return DirectedEdge.new(p1, p0) + + func equals(e:DirectedEdge)->bool: + return p0 == e.p0 && p1 == e.p1 + +class Facet extends RefCounted: + var plane:Plane + var points:PackedVector3Array #Clockwise winding faces out + var over_points:PackedVector3Array + + func _to_string(): + var result:String = "plane %s\ncentroid %s\npoints %s\nover %s" % [plane, (points[0] + points[1] + points[2])/3, points, over_points] + + return result + + func has_edge(e:DirectedEdge)->bool: + return (points[0] == e.p0 && points[1] == e.p1) || \ + (points[1] == e.p0 && points[2] == e.p1) || \ + (points[2] == e.p0 && points[0] == e.p1) + + func get_edges()->Array[DirectedEdge]: + var result:Array[DirectedEdge] = [] + + result.append(DirectedEdge.new(points[0], points[1])) + result.append(DirectedEdge.new(points[1], points[2])) + result.append(DirectedEdge.new(points[2], points[0])) + return result + + func init_from_points(p0:Vector3, p1:Vector3, p2:Vector3): + #Facet normal points to outside + plane = Plane(p0, p1, p2) + points = [p0, p1, p2] + + #Create a facet with vertices at p0, p1, p2 and winding such that under_ref + # is on the under side of the plane + func init_from_points_under(p0:Vector3, p1:Vector3, p2:Vector3, under_ref:Vector3): + #Facet normal points to outside + plane = Plane(p0, p1, p2) + if plane.is_point_over(under_ref): + plane = Plane(p0, p2, p1) + points = [p0, p2, p1] + else: + points = [p0, p1, p2] + + func get_furthest_point()->Vector3: + var best_point:Vector3 + var best_distance:float = 0 + + for p in over_points: + var dist = abs(plane.distance_to(p)) + if dist > best_distance: + best_point = p + best_distance = dist + + return best_point + +class Hull extends RefCounted: + var facets:Array[Facet] = [] + + func get_non_empty_facet()->Facet: + for f in facets: + if !f.over_points.is_empty(): + return f + return null + + func get_facet_with_edge(e:DirectedEdge)->Facet: + for f in facets: + if f.has_edge(e): + return f + return null + + func _to_string(): + var result:String = "" + for f in facets: + result += "%s\n" % f + return result + + + func get_points()->Array[Vector3]: + var result:Array[Vector3] + + for f in facets: + for p in f.points: + if !result.any(func(pl):return pl.is_equal_approx(p)): + result.append(p) + + return result + + func format_points()->String: + var result:String = "" + for f in facets: + result += "%s,\n" % f.points + return result + + +static func form_loop(edges:Array[DirectedEdge])->PackedVector3Array: + var sorted:Array[DirectedEdge] = [] + + var cur_edge:DirectedEdge = edges.pop_back() + sorted.append(cur_edge) + + while !edges.is_empty(): + var found_edge:bool = false + for i in edges.size(): + var e:DirectedEdge = edges[i] + if e.p0.is_equal_approx(cur_edge.p1): + edges.remove_at(i) + cur_edge = e + sorted.append(e) + found_edge = true + break + + if !found_edge: + assert(found_edge, "Unable to complete loop") + pass +# if !found_edge: +# assert(false, "Unable to complete loop") +# return PackedVector3Array() + + var result:PackedVector3Array + for e in sorted: + result.append(e.p0) + return result + +static func merge_coplanar_facets(hull:Hull)->Hull: +# print("hull %s " % hull) + #print("hull %s " % hull.format_points()) + + var new_hull:Hull = Hull.new() + var already_seen:Array[Facet] = [] + + for facet_idx in hull.facets.size(): + var facet:Facet = hull.facets[facet_idx] + if already_seen.has(facet): + continue + already_seen.append(facet) + + #print("merging facet %s" % facet) + + var neighbor_set:Array[Facet] = [] + neighbor_set.append(facet) + var boundary:Array[DirectedEdge] = [] + + while !neighbor_set.is_empty(): + var cur_facet:Facet = neighbor_set.pop_back() + var edges:Array[DirectedEdge] = cur_facet.get_edges() + + for e in edges: + var neighbor:Facet = hull.get_facet_with_edge(e.reverse()) + if neighbor.plane.is_equal_approx(facet.plane): + if !already_seen.has(neighbor): + already_seen.append(neighbor) + neighbor_set.append(neighbor) + else: + boundary.append(e) + + + var points:PackedVector3Array = form_loop(boundary) + + var nf:Facet = Facet.new() + nf.plane = facet.plane + nf.points = points + new_hull.facets.append(nf) + + return new_hull + + +static func create_initial_simplex(points:PackedVector3Array)->Hull: + if points.size() < 4: + return null + + #For first two points, pick furthest apart along one of the axes + var max_x:Vector3 = points[0] + var min_x:Vector3 = points[0] + var max_y:Vector3 = points[0] + var min_y:Vector3 = points[0] + var max_z:Vector3 = points[0] + var min_z:Vector3 = points[0] + + for idx in range(1, points.size()): + var p:Vector3 = points[idx] + if p.x > max_x.x: + max_x = p + if p.x < min_x.x: + min_x = p + if p.y > max_y.y: + max_y = p + if p.y < min_y.y: + min_y = p + if p.z > max_z.z: + max_z = p + if p.z < min_z.z: + min_z = p + + var p0:Vector3 + var p1:Vector3 + var dx:float = max_x.distance_squared_to(min_x) + var dy:float = max_y.distance_squared_to(min_y) + var dz:float = max_z.distance_squared_to(min_z) + + if dx > dy and dx > dz: + p0 = max_x + p1 = min_x + elif dy > dz: + p0 = max_y + p1 = min_y + else: + p0 = max_z + p1 = min_z + + #Find furthest point from line for second point + var p2:Vector3 = MathUtil.furthest_point_from_line(p0, p1 - p0, points) + var p3:Vector3 = MathUtil.furthest_point_from_plane(Plane(p0, p1, p2), points) + + #Make simplex + var hull:Hull = Hull.new() + + var f0:Facet = Facet.new() + f0.init_from_points_under(p1, p2, p3, p0) + var f1:Facet = Facet.new() + f1.init_from_points_under(p2, p3, p0, p1) + var f2:Facet = Facet.new() + f2.init_from_points_under(p3, p0, p1, p2) + var f3:Facet = Facet.new() + f3.init_from_points_under(p0, p1, p2, p3) + + hull.facets.append(f0) + hull.facets.append(f1) + hull.facets.append(f2) + hull.facets.append(f3) + + for p in points: + for f in hull.facets: + if f.plane.is_point_over(p) && !f.plane.has_point(p): + f.over_points.append(p) + + return hull + + +static func quickhull(points:PackedVector3Array)->Hull: + if points.size() < 4: + return null + + var hull:Hull = create_initial_simplex(points) + if !hull: + return null + + #print("initial points %s" % points) + #print("initial simplex %s" % hull.format_points()) + + while true: + var facet:Facet = hull.get_non_empty_facet() + if facet == null: + break + + #print("-facet %s" % facet) + + var p_over:Vector3 = facet.get_furthest_point() + #print("over point %s" % p_over) + + #print("hull %s" % hull.format_points()) + + var visibile_faces:Array[Facet] = [facet] + var edges:Array[DirectedEdge] = facet.get_edges() + var visited_edges:Array[DirectedEdge] = [] + var boundary_edges:Array[DirectedEdge] = [] + +# for e in edges: +# print("init edge search set %s" % e) + + + #Find set of edges that form the boundary of faces visible to point + # being added. We're basically flood filling from central facet until + # we hit faces pointing away from reference point. + while !edges.is_empty(): + var edge:DirectedEdge = edges.pop_back() + visited_edges.append(edge) + var edge_inv:DirectedEdge = edge.reverse() + + var neighbor_facet:Facet = hull.get_facet_with_edge(edge_inv) + if neighbor_facet.plane.is_point_over(p_over): + visibile_faces.append(neighbor_facet) + visited_edges.append(edge_inv) + var neighbor_edges:Array[DirectedEdge] = neighbor_facet.get_edges() + for e in neighbor_edges: + if !visited_edges.any(func(edge): return edge.equals(e)): + #print("adding edge to search set %s" % e) + edges.append(e) + else: + boundary_edges.append(edge) + #print("adding edge to boundary set %s" % edge) + + var remaining_over_points:PackedVector3Array + for f in visibile_faces: + for pf in f.over_points: + if pf == p_over: + continue + if !remaining_over_points.has(pf): + remaining_over_points.append(pf) + #print("over point for test %s" % pf) + + hull.facets.remove_at(hull.facets.find(f)) + + for e in boundary_edges: + var f:Facet = Facet.new() + f.init_from_points(e.p0, e.p1, p_over) + hull.facets.append(f) + + #print("adding facet %s" % f) + + for p in remaining_over_points: + if f.plane.is_point_over(p) && !f.plane.has_point(p): + f.over_points.append(p) + + #print("hull %s" % hull.format_points()) + + hull = merge_coplanar_facets(hull) + return hull + + + diff --git a/addons/cyclops_level_builder/menu/action_popup_menu.gd b/addons/cyclops_level_builder/menu/action_popup_menu.gd new file mode 100644 index 0000000..4ac8a73 --- /dev/null +++ b/addons/cyclops_level_builder/menu/action_popup_menu.gd @@ -0,0 +1,46 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends PopupMenu +class_name ActionPopupMenu + +var action_map:Dictionary = {} + +func _ready(): + id_pressed.connect(on_id_pressed) + +func add_action_item(action:CyclopsAction): +# var id:int = action_map.size() + var id:int = action_map.size() + 1000 + add_item(action.name, id, action.accellerator) + action_map[id] = action + +#func add_separator(label:String, id:int = -1): +# pass + +func on_id_pressed(id:int): + var action:CyclopsAction = action_map[id] + action._execute() + + diff --git a/addons/cyclops_level_builder/menu/editor_toolbar.gd b/addons/cyclops_level_builder/menu/editor_toolbar.gd new file mode 100644 index 0000000..b69d916 --- /dev/null +++ b/addons/cyclops_level_builder/menu/editor_toolbar.gd @@ -0,0 +1,166 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends PanelContainer +class_name EditorToolbar + +var editor_plugin:CyclopsLevelBuilder: + get: + return editor_plugin + set(value): + editor_plugin = value + editor_plugin.active_node_changed.connect(on_active_node_changed) +#var editor_plugin:CyclopsLevelBuilder + +#var action_map:Array[CyclopsAction] + +func on_active_node_changed(): + update_grid() + + +# Called when the node enters the scene tree for the first time. +func _ready(): + $HBoxContainer/grid_size.clear() + $HBoxContainer/grid_size.add_item("1/16", 0) + $HBoxContainer/grid_size.add_item("1/8", 1) + $HBoxContainer/grid_size.add_item("1/4", 2) + $HBoxContainer/grid_size.add_item("1/2", 3) + $HBoxContainer/grid_size.add_item("1", 4) + $HBoxContainer/grid_size.add_item("2", 5) + $HBoxContainer/grid_size.add_item("4", 6) + $HBoxContainer/grid_size.add_item("8", 7) + $HBoxContainer/grid_size.add_item("16", 8) + + $HBoxContainer/MenuBar/Menu.clear() + $HBoxContainer/MenuBar/Menu.add_action_item(ActionToolDuplicate.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionMergeSelectedBlocks.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionDeleteSelectedBlocks.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionSnapToGrid.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_separator() + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateX90Ccw.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateX90Cw.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateX180.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionMirrorSelectionX2.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_separator() + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateY90Ccw.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateY90Cw.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateY180.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionMirrorSelectionY2.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_separator() + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateZ90Ccw.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateZ90Cw.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateZ180.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionMirrorSelectionZ.new(editor_plugin)) + + update_grid() + +func update_grid(): + if !editor_plugin: + return + + if editor_plugin.active_node: + var size:int = editor_plugin.get_global_scene().grid_size + $HBoxContainer/grid_size.select(size + 4) + + $HBoxContainer/display_mode.select(editor_plugin.display_mode) + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass + + +func _on_grid_size_item_selected(index): +# if Engine.is_editor_hint(): + #print("_on_grid_size_item_selected " + str(index)) + +# if editor_plugin.active_node: + editor_plugin.get_global_scene().grid_size = index - 4 + + +func _on_bn_move_pressed(): + editor_plugin.switch_to_tool(ToolBlock.new()) + + +func _on_bn_clip_pressed(): + editor_plugin.switch_to_tool(ToolClip.new()) + + +func _on_bn_vertex_pressed(): + editor_plugin.switch_to_tool(ToolEditVertex.new()) + + +func _on_bn_edge_pressed(): + editor_plugin.switch_to_tool(ToolEditEdge.new()) + + +func _on_bn_face_pressed(): + editor_plugin.switch_to_tool(ToolEditFace.new()) + + +func _on_check_lock_uvs_toggled(button_pressed): + editor_plugin.lock_uvs = button_pressed + + +func _on_bn_prism_pressed(): + editor_plugin.switch_to_tool(ToolPrism.new()) + +func _on_bn_cylinder_pressed(): + editor_plugin.switch_to_tool(ToolCylinder.new()) + +func _on_bn_stairs_pressed(): + editor_plugin.switch_to_tool(ToolStairs.new()) + +func _on_bn_duplicate_pressed(): + editor_plugin.switch_to_tool(ToolDuplicate.new()) + + +func _on_bn_delete_pressed(): + var blocks_root:CyclopsBlocks = editor_plugin.active_node + var cmd:CommandDeleteBlocks = CommandDeleteBlocks.new() + cmd.blocks_root_path = blocks_root.get_path() + cmd.builder = editor_plugin + if cmd.will_change_anything(): + var undo:EditorUndoRedoManager = editor_plugin.get_undo_redo() + cmd.add_to_undo_manager(undo) + + +func _on_bn_flip_x_pressed(): + var action:ActionMirrorSelectionX2 = ActionMirrorSelectionX2.new(editor_plugin) + action._execute() + +func _on_bn_flip_y_pressed(): + var action:ActionMirrorSelectionY2 = ActionMirrorSelectionY2.new(editor_plugin) + action._execute() + + +func _on_bn_flip_z_pressed(): + var action:ActionMirrorSelectionZ = ActionMirrorSelectionZ.new(editor_plugin) + action._execute() + + +func _on_display_mode_item_selected(index): + editor_plugin.display_mode = index + + diff --git a/addons/cyclops_level_builder/menu/editor_toolbar.tscn b/addons/cyclops_level_builder/menu/editor_toolbar.tscn new file mode 100644 index 0000000..8683323 --- /dev/null +++ b/addons/cyclops_level_builder/menu/editor_toolbar.tscn @@ -0,0 +1,217 @@ +[gd_scene load_steps=6 format=3 uid="uid://c3cl77r65dexu"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/menu/editor_toolbar.gd" id="1_o71fd"] +[ext_resource type="Script" path="res://addons/cyclops_level_builder/menu/action_popup_menu.gd" id="2_ni0c8"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_o7kxq"] + +[sub_resource type="Theme" id="Theme_0hxey"] +PanelContainer/styles/panel = SubResource("StyleBoxEmpty_o7kxq") + +[sub_resource type="ButtonGroup" id="ButtonGroup_i8xwa"] + +[node name="PanelContainer" type="PanelContainer"] +offset_right = 739.0 +offset_bottom = 31.0 +size_flags_horizontal = 3 +theme = SubResource("Theme_0hxey") +script = ExtResource("1_o71fd") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 + +[node name="bn_block" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Click and drag in empty space or on unselected block to create a new block. + +Click and drag on a selected block to move it in the XZ plane. Hold Alt to drag along the Y axis. + +Ctrl-click and drag on the face of a block to move the face along its normal. + +Escape or right click to cancel drawing the block. + +Click on block to select it. Shift-Click toggles, Ctrl-Click adds and Shift-Ctrl Click subtracts. + +Click in empty space to clear selection." +toggle_mode = true +button_pressed = true +button_group = SubResource("ButtonGroup_i8xwa") +text = "Block" + +[node name="bn_prism" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Click on surface of block or in empty space to begin creating base of a prism. + +Click to add new point. Backspace to remove the last point you added. You can also right click on a point to remove it. + +Press Enter to extrude base. + +Press Enter again to finish extruding and create block." +toggle_mode = true +button_group = SubResource("ButtonGroup_i8xwa") +text = "Prism" + +[node name="bn_cylinder" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Click on surface of block or in empty space to begin creating base of a cylinder. + +Release the mouse to enter height drawing mode. If you have the tube option selected, you will draw the second ring instead. + +Use the mouse wheel to change the number of sides of the cylinder while drawing." +toggle_mode = true +button_group = SubResource("ButtonGroup_i8xwa") +text = "Cylinder" + +[node name="bn_stairs" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Click on surface of block or in empty space to begin creating base of a stair case. + +Release mouse button and drag upwards to adjust the height of the stairs. + +Use the mouse wheel to change the direction the stairs face. Ctrl-Wheel to change the height of each step, Ctrl-Shift-Wheel to change the depth of each step." +toggle_mode = true +button_group = SubResource("ButtonGroup_i8xwa") +text = "Stairs" + +[node name="bn_clip" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Click on surface of block to place first cutting point. + +Click again to place second cutting point. This will define the plane block will be cut along. + +If you press Enter at this point, the block will be cut. The cutting plane will be defined by the cutting line you've drawn and the normal of the plane it is on. + +You can optionally place a third cutting point. If you do, the three placed points will define the cutting plane when you press Enter. + +Press Backspace to delete the last cutting point you placed." +toggle_mode = true +button_group = SubResource("ButtonGroup_i8xwa") +text = "Clip" + +[node name="bn_vertex" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Click on a vertex to select it. Shift Click to toggle selecton, Ctrl Click to add to selection, Shift-Ctrl click to subtract from selection. + +Click and drag to move vertex in XZ plane. Hold Alt to drag along Y axis. Click and drag on a selected vertex to move all selected vertices. + +Hover the mouse over a different block and press Alt-Q to switch to editing that block." +toggle_mode = true +button_group = SubResource("ButtonGroup_i8xwa") +text = "Vertex" + +[node name="bn_edge" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Click on an edge to select it. Shift Click to toggle selecton, Ctrl Click to add to selection, Shift-Ctrl click to subtract from selection. + +Click and drag to move edge in XZ plane. Hold Alt to drag along Y axis. Click and drag on a selected edge to move all selected edges. + +Hover the mouse over a different block and press Alt-Q to switch to editing that block." +toggle_mode = true +button_group = SubResource("ButtonGroup_i8xwa") +text = "Edge" + +[node name="bn_face" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Click on a face to select it. Shift Click to toggle selecton, Ctrl Click to add to selection, Shift-Ctrl click to subtract from selection. + +Click and drag to move face in XZ plane. Hold Alt to drag along Y axis. Click and drag on a selected face to move all selected faces. + +Hover the mouse over a different block and press Alt-Q to switch to editing that block." +toggle_mode = true +button_group = SubResource("ButtonGroup_i8xwa") +text = "Face" + +[node name="MenuBar" type="MenuBar" parent="HBoxContainer"] +layout_mode = 2 + +[node name="Menu" type="PopupMenu" parent="HBoxContainer/MenuBar"] +item_count = 18 +item_0/text = "Duplicate Selected Blocks" +item_0/id = 1000 +item_1/text = "Delete Selected Blocks" +item_1/id = 1001 +item_2/text = "Snap to grid" +item_2/id = 1002 +item_3/text = "" +item_3/id = -1 +item_3/separator = true +item_4/text = "Rotate 90 Ccw X" +item_4/id = 1003 +item_5/text = "Rotate 90 Cw X" +item_5/id = 1004 +item_6/text = "Rotate 180 X" +item_6/id = 1005 +item_7/text = "Mirror Selection X" +item_7/id = 1006 +item_8/text = "" +item_8/id = -1 +item_8/separator = true +item_9/text = "Rotate 90 Ccw Y" +item_9/id = 1007 +item_10/text = "Rotate 90 Cw Y" +item_10/id = 1008 +item_11/text = "Rotate 180 Y" +item_11/id = 1009 +item_12/text = "Mirror Selection Y" +item_12/id = 1010 +item_13/text = "" +item_13/id = -1 +item_13/separator = true +item_14/text = "Rotate 90 Ccw Z" +item_14/id = 1011 +item_15/text = "Rotate 90 Cw Z" +item_15/id = 1012 +item_16/text = "Rotate 180 Z" +item_16/id = 1013 +item_17/text = "Mirror Selection Z" +item_17/id = 1014 +script = ExtResource("2_ni0c8") + +[node name="check_lock_uvs" type="CheckBox" parent="HBoxContainer"] +layout_mode = 2 +text = "Lock UVs" + +[node name="grid_size" type="OptionButton" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Grid snapping size" +item_count = 9 +selected = 0 +popup/item_0/text = "1/16" +popup/item_0/id = 0 +popup/item_1/text = "1/8" +popup/item_1/id = 1 +popup/item_2/text = "1/4" +popup/item_2/id = 2 +popup/item_3/text = "1/2" +popup/item_3/id = 3 +popup/item_4/text = "1" +popup/item_4/id = 4 +popup/item_5/text = "2" +popup/item_5/id = 5 +popup/item_6/text = "4" +popup/item_6/id = 6 +popup/item_7/text = "8" +popup/item_7/id = 7 +popup/item_8/text = "16" +popup/item_8/id = 8 + +[node name="display_mode" type="OptionButton" parent="HBoxContainer"] +layout_mode = 2 +item_count = 2 +selected = 1 +popup/item_0/text = "Wireframe" +popup/item_0/id = 0 +popup/item_1/text = "Textured" +popup/item_1/id = 1 + +[connection signal="pressed" from="HBoxContainer/bn_block" to="." method="_on_bn_move_pressed"] +[connection signal="pressed" from="HBoxContainer/bn_prism" to="." method="_on_bn_prism_pressed"] +[connection signal="pressed" from="HBoxContainer/bn_cylinder" to="." method="_on_bn_cylinder_pressed"] +[connection signal="pressed" from="HBoxContainer/bn_stairs" to="." method="_on_bn_stairs_pressed"] +[connection signal="pressed" from="HBoxContainer/bn_clip" to="." method="_on_bn_clip_pressed"] +[connection signal="pressed" from="HBoxContainer/bn_vertex" to="." method="_on_bn_vertex_pressed"] +[connection signal="pressed" from="HBoxContainer/bn_edge" to="." method="_on_bn_edge_pressed"] +[connection signal="pressed" from="HBoxContainer/bn_face" to="." method="_on_bn_face_pressed"] +[connection signal="toggled" from="HBoxContainer/check_lock_uvs" to="." method="_on_check_lock_uvs_toggled"] +[connection signal="item_selected" from="HBoxContainer/grid_size" to="." method="_on_grid_size_item_selected"] +[connection signal="item_selected" from="HBoxContainer/display_mode" to="." method="_on_display_mode_item_selected"] diff --git a/addons/cyclops_level_builder/menu/sticky_toolbar.gd b/addons/cyclops_level_builder/menu/sticky_toolbar.gd new file mode 100644 index 0000000..c9be86e --- /dev/null +++ b/addons/cyclops_level_builder/menu/sticky_toolbar.gd @@ -0,0 +1,41 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Control +class_name StickyToolbar + +var plugin:CyclopsLevelBuilder + +# Called when the node enters the scene tree for the first time. +func _ready(): + $HBoxContainer/PanelContainer.visible = false + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass + + +func _on_texture_button_toggled(button_pressed): + $HBoxContainer/PanelContainer.visible = button_pressed diff --git a/addons/cyclops_level_builder/menu/sticky_toolbar.tscn b/addons/cyclops_level_builder/menu/sticky_toolbar.tscn new file mode 100644 index 0000000..4a1db9f --- /dev/null +++ b/addons/cyclops_level_builder/menu/sticky_toolbar.tscn @@ -0,0 +1,41 @@ +[gd_scene load_steps=8 format=3 uid="uid://c4smddvlwx54s"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/menu/sticky_toolbar.gd" id="1_52wtc"] +[ext_resource type="Texture2D" uid="uid://d0krdms4l6ns4" path="res://addons/cyclops_level_builder/art/cyclops_3.png" id="2_0mx5n"] +[ext_resource type="Texture2D" uid="uid://cg3yjatinkymb" path="res://addons/cyclops_level_builder/art/cyclops_4.png" id="3_5oy58"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_h0l71"] + +[sub_resource type="Theme" id="Theme_dgoud"] +PanelContainer/styles/panel = SubResource("StyleBoxEmpty_h0l71") + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_6pjef"] + +[sub_resource type="Theme" id="Theme_nckdr"] +PanelContainer/styles/panel = SubResource("StyleBoxEmpty_6pjef") + +[node name="PanelContainer" type="PanelContainer"] +offset_right = 70.0 +offset_bottom = 31.0 +theme = SubResource("Theme_dgoud") +script = ExtResource("1_52wtc") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 + +[node name="CyclopsButton" type="TextureButton" parent="HBoxContainer"] +layout_mode = 2 +toggle_mode = true +texture_normal = ExtResource("2_0mx5n") +texture_pressed = ExtResource("3_5oy58") + +[node name="PanelContainer" type="PanelContainer" parent="HBoxContainer"] +visible = false +layout_mode = 2 +theme = SubResource("Theme_nckdr") + +[node name="Button" type="Button" parent="HBoxContainer/PanelContainer"] +layout_mode = 2 +text = "Block" + +[connection signal="toggled" from="HBoxContainer/CyclopsButton" to="." method="_on_texture_button_toggled"] diff --git a/addons/cyclops_level_builder/nodes/cyclops_blocks.gd b/addons/cyclops_level_builder/nodes/cyclops_blocks.gd new file mode 100644 index 0000000..c5f97e6 --- /dev/null +++ b/addons/cyclops_level_builder/nodes/cyclops_blocks.gd @@ -0,0 +1,143 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Node3D +class_name CyclopsBlocks + +signal blocks_changed + +@export var occluder_vertex_offset:float = 0: + get: + return occluder_vertex_offset + set(value): + occluder_vertex_offset = value + dirty = true + +var dirty:bool = true + +var block_bodies:Node3D + +# Called when the node enters the scene tree for the first time. +func _ready(): + + child_entered_tree.connect(on_child_entered_tree) + child_exiting_tree.connect(on_child_exiting_tree) + + block_bodies = Node3D.new() + block_bodies.name = "block_bodies" + add_child(block_bodies) + + for node in get_children(): + if node is CyclopsConvexBlock: + var block:CyclopsConvexBlock = node + block.mesh_changed.connect(on_child_mesh_changed) + + + +func on_child_mesh_changed(): + dirty = true + blocks_changed.emit() + + +func on_child_entered_tree(node:Node): + if node is CyclopsConvexBlock: + var block:CyclopsConvexBlock = node + block.mesh_changed.connect(on_child_mesh_changed) + +# print("on_child_entered_tree %s" % node.name) + dirty = true + +func on_child_exiting_tree(node:Node): + if node is CyclopsConvexBlock: + var block:CyclopsConvexBlock = node + block.mesh_changed.disconnect(on_child_mesh_changed) + +# print("on_child_exited_tree %s" % node.name) + + dirty = true + +func has_selected_blocks()->bool: + for child in get_children(): + if child is CyclopsConvexBlock and child.selected: + return true + return false + + +func rebuild_mesh(): + for child in block_bodies.get_children(): + child.queue_free() + + for child in get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + +# var block_body:CyclopsConvexBlockBody = preload("res://addons/cyclops_level_builder/nodes/cyclops_convex_block_body.gd").instantiate() + var block_body:CyclopsConvexBlockBody = CyclopsConvexBlockBody.new() + block_body.materials = block.materials + block_body.block_data = block.block_data + block_bodies.add_child(block_body) + + + dirty = false + +func get_active_block()->CyclopsConvexBlock: + for child in get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.active: + return block + return null + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + if dirty: + rebuild_mesh() + +func _input(event): + if Engine.is_editor_hint(): + pass + + #print(event.as_text()) + pass + +func intersect_ray_closest(origin:Vector3, dir:Vector3)->IntersectResults: + return intersect_ray_closest_filtered(origin, dir, func(block:CyclopsConvexBlock): return true) + +func intersect_ray_closest_selected_only(origin:Vector3, dir:Vector3)->IntersectResults: + return intersect_ray_closest_filtered(origin, dir, func(block:CyclopsConvexBlock): return block.selected) + +func intersect_ray_closest_filtered(origin:Vector3, dir:Vector3, filter:Callable)->IntersectResults: + var best_result:IntersectResults + + for child in get_children(): + if child is CyclopsConvexBlock: + var result:IntersectResults = child.intersect_ray_closest(origin, dir) + if result: + if !filter.call(result.object): + continue + + if !best_result or result.distance_squared < best_result.distance_squared: + best_result = result + + return best_result diff --git a/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.png b/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.png new file mode 100644 index 0000000..89a3bc2 Binary files /dev/null and b/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.png differ diff --git a/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.png.import b/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.png.import new file mode 100644 index 0000000..d1622bc --- /dev/null +++ b/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bdmaqfi82aq41" +path="res://.godot/imported/cyclops_blocks_icon.png-24c4441d9ebe4c1c02b0cf9fcbf537f3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/nodes/cyclops_blocks_icon.png" +dest_files=["res://.godot/imported/cyclops_blocks_icon.png-24c4441d9ebe4c1c02b0cf9fcbf537f3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.svg b/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.svg new file mode 100644 index 0000000..9d6e240 --- /dev/null +++ b/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + diff --git a/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.svg.import b/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.svg.import new file mode 100644 index 0000000..1c1ce7d --- /dev/null +++ b/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://chuwp6awho53q" +path="res://.godot/imported/cyclops_blocks_icon.svg-5e216ef2489ff1d30c472c6b8748fdf1.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/nodes/cyclops_blocks_icon.svg" +dest_files=["res://.godot/imported/cyclops_blocks_icon.svg-5e216ef2489ff1d30c472c6b8748fdf1.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/cyclops_level_builder/nodes/cyclops_convex_block.gd b/addons/cyclops_level_builder/nodes/cyclops_convex_block.gd new file mode 100644 index 0000000..0355079 --- /dev/null +++ b/addons/cyclops_level_builder/nodes/cyclops_convex_block.gd @@ -0,0 +1,123 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Node +class_name CyclopsConvexBlock + +signal mesh_changed + +@export var materials:Array[Material] + +var control_mesh:ConvexVolume + +var selected:bool = false: + get: + return selected + set(value): + if value == selected: + return + selected = value + mesh_changed.emit() + +var active:bool: + get: + return active + set(value): + if value == active: + return + active = value + mesh_changed.emit() + + +var default_material:Material = preload("res://addons/cyclops_level_builder/materials/grid.tres") + +@export var block_data:ConvexBlockData: + get: + return block_data + set(value): + if block_data != value: + block_data = value + control_mesh = ConvexVolume.new() + control_mesh.init_from_convex_block_data(block_data) + + mesh_changed.emit() + + +func intersect_ray_closest(origin:Vector3, dir:Vector3)->IntersectResults: + if !block_data: + return null + + var result:IntersectResults = control_mesh.intersect_ray_closest(origin, dir) + if result: + result.object = self + + return result + + +func select_face(face_idx:int, select_type:Selection.Type = Selection.Type.REPLACE): + if select_type == Selection.Type.REPLACE: + for f in control_mesh.faces: + f.selected = f.index == face_idx + elif select_type == Selection.Type.ADD: + control_mesh.faces[face_idx].selected = true + elif select_type == Selection.Type.SUBTRACT: + control_mesh.faces[face_idx].selected = true + elif select_type == Selection.Type.TOGGLE: + control_mesh.faces[face_idx].selected = !control_mesh.faces[face_idx].selected + + mesh_changed.emit() + +func append_mesh(mesh:ImmediateMesh): +# print("adding block mesh %s" % name) + #var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + + control_mesh.append_mesh(mesh, materials, default_material) + +func append_mesh_wire(mesh:ImmediateMesh): + var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + + var mat:Material = global_scene.outline_material + control_mesh.append_mesh_wire(mesh, mat) + +func append_mesh_backfacing(mesh:ImmediateMesh): + var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + + var mat:Material = global_scene.tool_object_selected_material + control_mesh.append_mesh_backfacing(mesh, mat) + +func append_mesh_outline(mesh:ImmediateMesh, viewport_camera:Camera3D, local_to_world:Transform3D): + var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + + var mat:Material = global_scene.tool_object_active_material if active else global_scene.tool_object_selected_material + control_mesh.append_mesh_outline(mesh, viewport_camera, local_to_world, mat) + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass + diff --git a/addons/cyclops_level_builder/nodes/cyclops_convex_block_body.gd b/addons/cyclops_level_builder/nodes/cyclops_convex_block_body.gd new file mode 100644 index 0000000..3aa5799 --- /dev/null +++ b/addons/cyclops_level_builder/nodes/cyclops_convex_block_body.gd @@ -0,0 +1,141 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Node3D +class_name CyclopsConvexBlockBody + +var mesh_instance:MeshInstance3D +var mesh_wire:MeshInstance3D +var collision_body:StaticBody3D +var collision_shape:CollisionShape3D +var occluder:OccluderInstance3D + +var dirty:bool = true + +@export var block_data:ConvexBlockData: + get: + return block_data + set(value): + block_data = value + dirty = true + + +@export var materials:Array[Material] + +var default_material:Material = preload("res://addons/cyclops_level_builder/materials/grid.tres") +var display_mode:DisplayMode.Type = DisplayMode.Type.TEXTURED + +# Called when the node enters the scene tree for the first time. +func _ready(): + mesh_instance = MeshInstance3D.new() + add_child(mesh_instance) + mesh_instance.gi_mode = GeometryInstance3D.GI_MODE_STATIC + + if Engine.is_editor_hint(): + mesh_wire = MeshInstance3D.new() + add_child(mesh_wire) + + collision_body = StaticBody3D.new() + add_child(collision_body) + collision_shape = CollisionShape3D.new() + collision_body.add_child(collision_shape) + + occluder = OccluderInstance3D.new() + add_child(occluder) + + build_from_block() + + +func build_from_block(): + + dirty = false + + mesh_instance.mesh = null + collision_shape.shape = null + + if Engine.is_editor_hint(): +# var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + var global_scene = get_node("/root/CyclopsAutoload") + display_mode = global_scene.builder.display_mode + +# print("block_data %s" % block_data) +# print("vert points %s" % block_data.vertex_points) + if !block_data: + return + +# print("got block data") + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(block_data) + + #print("volume %s" % vol) + +# var mesh:ImmediateMesh = ImmediateMesh.new() + var mesh:ArrayMesh + + if Engine.is_editor_hint(): +# var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + var global_scene = get_node("/root/CyclopsAutoload") + mesh_wire.mesh = vol.create_mesh_wire(global_scene.outline_material) + #print ("added wireframe") + + if display_mode == DisplayMode.Type.TEXTURED: + mesh = vol.create_mesh(materials, default_material) + #print ("added faces") + else: + mesh = vol.create_mesh(materials, default_material) +# vol.append_mesh(mesh, materials, default_material) + + mesh_instance.mesh = mesh + +# print("===============") +# GeneralUtil.dump_properties(mesh_instance) +# print("---------------") +# GeneralUtil.dump_properties(mesh_instance.mesh) + + var shape:ConvexPolygonShape3D = ConvexPolygonShape3D.new() + shape.points = vol.get_points() + collision_shape.shape = shape + + if !Engine.is_editor_hint(): + #Disabling this in the editor for now since this is causing slowdown + var occluder_object:ArrayOccluder3D = ArrayOccluder3D.new() + occluder_object.vertices = vol.get_points() + occluder_object.indices = vol.get_trimesh_indices() + occluder.occluder = occluder_object + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + if dirty: + build_from_block() + + + if Engine.is_editor_hint(): +# var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + var global_scene = get_node("/root/CyclopsAutoload") + + if display_mode != global_scene.builder.display_mode: + dirty = true + return + diff --git a/addons/cyclops_level_builder/nodes/intersect_results.gd b/addons/cyclops_level_builder/nodes/intersect_results.gd new file mode 100644 index 0000000..185ded0 --- /dev/null +++ b/addons/cyclops_level_builder/nodes/intersect_results.gd @@ -0,0 +1,35 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends RefCounted +class_name IntersectResults + +var object:CyclopsConvexBlock +var face_id:int +var position:Vector3 +var normal:Vector3 +var distance_squared:float + +func _to_string(): + return "object:%s face_id:%s pos:%s norm:%s dist_sq:%s" % [object, face_id, position, normal, distance_squared] diff --git a/addons/cyclops_level_builder/plugin.cfg b/addons/cyclops_level_builder/plugin.cfg new file mode 100644 index 0000000..39b8937 --- /dev/null +++ b/addons/cyclops_level_builder/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Cyclops Level Builder" +description="Tools for rapidly blocking in levels." +author="Mark McKay" +version="1.0.1" +script="cyclops_level_builder.gd" diff --git a/addons/cyclops_level_builder/resources/block_data.gd b/addons/cyclops_level_builder/resources/block_data.gd new file mode 100644 index 0000000..eb4a10d --- /dev/null +++ b/addons/cyclops_level_builder/resources/block_data.gd @@ -0,0 +1,32 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Resource +class_name BlockData + +@export var points:PackedVector3Array #Per vertex +@export var uvs:PackedVector2Array #Per face corner uv info +@export var face_vertex_indices:PackedInt32Array #Vertex index per face +@export var face_vertex_count:PackedInt32Array #Number of verts in each face +@export var face_material_indices:PackedInt32Array #Material index for each face diff --git a/addons/cyclops_level_builder/resources/convex_block_data.gd b/addons/cyclops_level_builder/resources/convex_block_data.gd new file mode 100644 index 0000000..aa5b53b --- /dev/null +++ b/addons/cyclops_level_builder/resources/convex_block_data.gd @@ -0,0 +1,51 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Resource +class_name ConvexBlockData + +@export var selected:bool = false +@export var active:bool = false +@export var collsion:bool = true + +@export var vertex_points:PackedVector3Array #Per vertex +@export var vertex_selected:PackedByteArray #Per vertex +#@export var vertex_active:PackedByteArray #Per vertex +@export var active_vertex:int + +@export var edge_vertex_indices:PackedInt32Array +@export var edge_selected:PackedByteArray +#@export var edge_active:PackedByteArray +@export var active_edge:int +@export var edge_face_indices:PackedInt32Array + +@export var face_vertex_count:PackedInt32Array #Number of verts in each face +@export var face_vertex_indices:PackedInt32Array #Vertex index per face +@export var face_material_indices:PackedInt32Array #Material index for each face +@export var face_uv_transform:Array[Transform2D] +@export var face_selected:PackedByteArray #Per face +#@export var face_active:PackedByteArray #Per face +@export var active_face:int +@export var face_ids:PackedInt32Array #Per face + diff --git a/addons/cyclops_level_builder/shaders/outline_shader.tres b/addons/cyclops_level_builder/shaders/outline_shader.tres new file mode 100644 index 0000000..7e78ea6 --- /dev/null +++ b/addons/cyclops_level_builder/shaders/outline_shader.tres @@ -0,0 +1,65 @@ +[gd_resource type="VisualShader" load_steps=5 format=3 uid="uid://cc5tovf48xmg1"] + +[sub_resource type="VisualShaderNodeColorConstant" id="VisualShaderNodeColorConstant_mqcg1"] +constant = Color(0, 0, 0, 1) + +[sub_resource type="VisualShaderNodeColorParameter" id="VisualShaderNodeColorParameter_kvn47"] +parameter_name = "ColorParameter" +default_value_enabled = true +default_value = Color(0, 0, 0, 1) + +[sub_resource type="VisualShaderNodeLinearSceneDepth" id="VisualShaderNodeLinearSceneDepth_d3ao7"] + +[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_pyrux"] +default_input_values = [0, 0.0, 1, 1.0] + +[resource] +code = "shader_type spatial; +uniform vec4 ColorParameter : source_color = vec4(0.000000, 0.000000, 0.000000, 1.000000); +uniform sampler2D depth_tex_frg_4 : hint_depth_texture; + + + +void fragment() { +// ColorConstant:2 + vec4 n_out2p0 = vec4(0.000000, 0.000000, 0.000000, 1.000000); + + +// ColorParameter:3 + vec4 n_out3p0 = ColorParameter; + + + float n_out4p0; +// LinearSceneDepth:4 + { + float __log_depth = textureLod(depth_tex_frg_4, SCREEN_UV, 0.0).x; + vec4 __depth_view = INV_PROJECTION_MATRIX * vec4(vec3(SCREEN_UV, __log_depth) * 2.0 - 1.0, 1.0); + __depth_view.xyz /= __depth_view.w; + n_out4p0 = -__depth_view.z; + } + + +// FloatOp:5 + float n_in5p1 = 1.00000; + float n_out5p0 = n_out4p0 + n_in5p1; + + +// Output:0 + ALBEDO = vec3(n_out2p0.xyz); + EMISSION = vec3(n_out3p0.xyz); + NORMAL_MAP_DEPTH = n_out5p0; + + +} +" +graph_offset = Vector2(-10.4364, 103.709) +nodes/fragment/0/position = Vector2(480, 140) +nodes/fragment/2/node = SubResource("VisualShaderNodeColorConstant_mqcg1") +nodes/fragment/2/position = Vector2(227.319, 156.469) +nodes/fragment/3/node = SubResource("VisualShaderNodeColorParameter_kvn47") +nodes/fragment/3/position = Vector2(80, 280) +nodes/fragment/4/node = SubResource("VisualShaderNodeLinearSceneDepth_d3ao7") +nodes/fragment/4/position = Vector2(0, 560) +nodes/fragment/5/node = SubResource("VisualShaderNodeFloatOp_pyrux") +nodes/fragment/5/position = Vector2(260, 520) +nodes/fragment/connections = PackedInt32Array(2, 0, 0, 0, 3, 0, 0, 5, 4, 0, 5, 0, 5, 0, 0, 10) diff --git a/addons/cyclops_level_builder/shaders/tool_outline_shader.tres b/addons/cyclops_level_builder/shaders/tool_outline_shader.tres new file mode 100644 index 0000000..ad3d116 --- /dev/null +++ b/addons/cyclops_level_builder/shaders/tool_outline_shader.tres @@ -0,0 +1,38 @@ +[gd_resource type="VisualShader" load_steps=3 format=3 uid="uid://c33k8fbmgw46b"] + +[sub_resource type="VisualShaderNodeColorConstant" id="VisualShaderNodeColorConstant_mqcg1"] +constant = Color(0, 0, 0, 1) + +[sub_resource type="VisualShaderNodeColorParameter" id="VisualShaderNodeColorParameter_kvn47"] +parameter_name = "ColorParameter" +default_value_enabled = true +default_value = Color(1, 1, 0, 1) + +[resource] +code = "shader_type spatial; +uniform vec4 ColorParameter : source_color = vec4(1.000000, 1.000000, 0.000000, 1.000000); + + + +void fragment() { +// ColorConstant:2 + vec4 n_out2p0 = vec4(0.000000, 0.000000, 0.000000, 1.000000); + + +// ColorParameter:3 + vec4 n_out3p0 = ColorParameter; + + +// Output:0 + ALBEDO = vec3(n_out2p0.xyz); + EMISSION = vec3(n_out3p0.xyz); + + +} +" +nodes/fragment/0/position = Vector2(480, 140) +nodes/fragment/2/node = SubResource("VisualShaderNodeColorConstant_mqcg1") +nodes/fragment/2/position = Vector2(227.319, 156.469) +nodes/fragment/3/node = SubResource("VisualShaderNodeColorParameter_kvn47") +nodes/fragment/3/position = Vector2(80, 280) +nodes/fragment/connections = PackedInt32Array(2, 0, 0, 0, 3, 0, 0, 5) diff --git a/addons/cyclops_level_builder/tools/cyclops_tool.gd b/addons/cyclops_level_builder/tools/cyclops_tool.gd new file mode 100644 index 0000000..416ec9f --- /dev/null +++ b/addons/cyclops_level_builder/tools/cyclops_tool.gd @@ -0,0 +1,105 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Resource +class_name CyclopsTool + +var builder:CyclopsLevelBuilder + +#func _init(_editorPlugin:EditorPlugin): +# editorPlugin = _editorPlugin + +func _activate(builder:CyclopsLevelBuilder): + self.builder = builder + +func _deactivate(): + pass + +func _get_tool_id()->String: + return "" + +func _draw_tool(viewport_camera:Camera3D): + pass + +func _get_tool_properties_editor()->Control: + return null + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if event is InputEventKey: + var e:InputEventKey = event + + if e.keycode == KEY_X: + if e.is_pressed(): + #print("cyc tool X") + var action:ActionDeleteSelectedBlocks = ActionDeleteSelectedBlocks.new(builder) + action._execute() + + return true + + if e.keycode == KEY_D: + if e.is_pressed(): + if e.shift_pressed && !Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT): + + if builder.active_node and builder.active_node.has_selected_blocks(): + + builder.switch_to_tool(ToolDuplicate.new()) + + return true + + if event is InputEventMouseButton: + var e:InputEventMouseButton = event + + if e.button_index == MOUSE_BUTTON_MIDDLE: + if e.alt_pressed: + if e.is_pressed(): + if builder.active_node: + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = builder.active_node.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + var result:IntersectResults = builder.active_node.intersect_ray_closest(origin_local, dir_local) + if result: + var ed_iface:EditorInterface = builder.get_editor_interface() + var base_control:Control = ed_iface.get_base_control() + + #viewport_camera + var new_cam_origin:Vector3 = result.position + \ + viewport_camera.global_transform.basis.z * builder.block_create_distance + viewport_camera.global_transform.origin = new_cam_origin + return true + + return false + + + +func to_local(point:Vector3, world_to_local:Transform3D, grid_step_size:float)->Vector3: + var p_local:Vector3 = world_to_local * point + + return MathUtil.snap_to_grid(p_local, grid_step_size) + diff --git a/addons/cyclops_level_builder/tools/tool_block.gd b/addons/cyclops_level_builder/tools/tool_block.gd new file mode 100644 index 0000000..29d256e --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_block.gd @@ -0,0 +1,349 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends CyclopsTool +class_name ToolBlock + +const TOOL_ID:String = "block" + +enum ToolState { NONE, READY, BLOCK_BASE, BLOCK_HEIGHT, MOVE_BLOCK, MOVE_FACE } +var tool_state:ToolState = ToolState.NONE +#enum State { READY, DRAG_BASE } +#var dragging:bool = false +var viewport_camera_start:Camera3D +var event_start:InputEventMouseButton + +var block_drag_cur:Vector3 +var block_drag_p0_local:Vector3 +var block_drag_p1_local:Vector3 +var block_drag_p2_local:Vector3 + +var drag_floor_normal:Vector3 + +#var min_drag_distance:float = 4 + +#Keep a copy of move command here while we are building it +var cmd_move_blocks:CommandMoveBlocks +var cmd_move_face:CommandMoveFacePlanar +var move_face_origin:Vector3 #Kep track of the origin when moving a face + +var base_points:PackedVector3Array + +func _get_tool_id()->String: + return TOOL_ID + +func start_block_drag(viewport_camera:Camera3D, event:InputEvent): + var blocks_root:CyclopsBlocks = self.builder.active_node + var e:InputEventMouseButton = event + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + +# print("origin %s dir %s" % [origin, dir]) + + var result:IntersectResults = blocks_root.intersect_ray_closest(origin, dir) +# print("result %s" % result) + + if result: +# print("Hit! %s" % result) + drag_floor_normal = MathUtil.snap_to_best_axis_normal(result.normal) + + var start_pos:Vector3 = result.position + var w2l = blocks_root.global_transform.inverse() + var start_pos_local:Vector3 = w2l * start_pos + + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + + block_drag_p0_local = MathUtil.snap_to_grid(start_pos_local, grid_step_size) + + if e.ctrl_pressed: + tool_state = ToolState.MOVE_FACE + + cmd_move_face = CommandMoveFacePlanar.new() + cmd_move_face.builder = builder + cmd_move_face.blocks_root_path = builder.active_node.get_path() + cmd_move_face.block_path = result.object.get_path() + cmd_move_face.face_id = result.face_id + cmd_move_face.lock_uvs = builder.lock_uvs + cmd_move_face.move_dir_normal = result.object.control_mesh.faces[result.face_id].normal + + move_face_origin = result.position + + elif result.object.selected: + tool_state = ToolState.MOVE_BLOCK + + cmd_move_blocks = CommandMoveBlocks.new() + cmd_move_blocks.builder = builder + cmd_move_blocks.lock_uvs = builder.lock_uvs + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock and child.selected: + cmd_move_blocks.add_block(child.get_path()) + else: + tool_state = ToolState.BLOCK_BASE + + + else: +# print("Miss") + drag_floor_normal = Vector3.UP + + tool_state = ToolState.BLOCK_BASE + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var start_pos_local:Vector3 = w2l * start_pos + + #print("start_pos %s" % start_pos) + #print("start_pos_local %s" % start_pos_local) + + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + + + #print("start_pos_local %s" % start_pos_local) + block_drag_p0_local = MathUtil.snap_to_grid(start_pos_local, grid_step_size) + + #print("block_drag_start_local %s" % block_drag_start_local) + #print("set 1 tool_state %s" % tool_state) + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + global_scene.draw_selected_blocks(viewport_camera) + + if tool_state == ToolState.BLOCK_BASE: + global_scene.draw_loop(base_points, true, global_scene.tool_material) + global_scene.draw_points(base_points, global_scene.tool_material) + + if tool_state == ToolState.BLOCK_HEIGHT: + global_scene.draw_cube(block_drag_p0_local, block_drag_p1_local, block_drag_cur, global_scene.tool_material) + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + var blocks_root:CyclopsBlocks = builder.active_node + + if event is InputEventKey: + var e:InputEventKey = event + + if e.keycode == KEY_ESCAPE: + if e.is_pressed(): + tool_state = ToolState.NONE + return true + + + elif event is InputEventMouseButton: + + var e:InputEventMouseButton = event + if e.button_index == MOUSE_BUTTON_LEFT: + + if e.is_pressed(): + if tool_state == ToolState.NONE: + event_start = event + viewport_camera_start = viewport_camera + + tool_state = ToolState.READY + + else: + if tool_state == ToolState.READY: + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var result:IntersectResults = blocks_root.intersect_ray_closest(origin, dir) + + var cmd:CommandSelectBlocks = CommandSelectBlocks.new() + cmd.builder = builder + cmd.selection_type = Selection.choose_type(e.shift_pressed, e.ctrl_pressed) + + if result: + cmd.block_paths.append(result.object.get_path()) + + if cmd.will_change_anything(): + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo) + + tool_state = ToolState.NONE + + elif tool_state == ToolState.BLOCK_BASE: + block_drag_p1_local = block_drag_cur + tool_state = ToolState.BLOCK_HEIGHT + + #print("set 2 tool_state %s" % tool_state) + + elif tool_state == ToolState.BLOCK_HEIGHT: +# print("Adding block %s %s %s" % [block_drag_p0_local, block_drag_p1_local, block_drag_p2_local]) + block_drag_p2_local = block_drag_cur + tool_state = ToolState.NONE + + var bounds:AABB = AABB(block_drag_p0_local, Vector3.ZERO) + bounds = bounds.expand(block_drag_p1_local) + bounds = bounds.expand(block_drag_p2_local) + +# print("AABB %s" % bounds) + + if bounds.has_volume(): + var command:CommandAddBlock2 = CommandAddBlock2.new() + + command.builder = builder + command.blocks_root_path = blocks_root.get_path() + command.block_name = GeneralUtil.find_unique_name(builder.active_node, "Block_") + command.bounds = bounds + command.uv_transform = builder.tool_uv_transform + command.material_path = builder.tool_material_path + + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + command.add_to_undo_manager(undo) + + elif tool_state == ToolState.MOVE_BLOCK: + + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd_move_blocks.add_to_undo_manager(undo) + + tool_state = ToolState.NONE + + elif tool_state == ToolState.MOVE_FACE: + + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd_move_face.add_to_undo_manager(undo) + + tool_state = ToolState.NONE + + return true + + elif e.button_index == MOUSE_BUTTON_RIGHT: + if tool_state == ToolState.BLOCK_BASE || tool_state == ToolState.BLOCK_HEIGHT: + if e.is_pressed(): + tool_state = ToolState.NONE + return true + + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + +# var global_scene:CyclopsGlobalScene = builder.get_node("/root/CyclopsAutoload") + + #print("tool_state %s" % tool_state) + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return super._gui_input(viewport_camera, event) + + if tool_state == ToolState.NONE: + if e.ctrl_pressed: + #block_drag_cur = MathUtil.intersect_plane(origin_local, dir_local, block_drag_p0_local, drag_floor_normal) + var result:IntersectResults = blocks_root.intersect_ray_closest(origin_local, dir_local) + if result: + var block:CyclopsConvexBlock = result.object + var convex_mesh:ConvexVolume = block.control_mesh + base_points = convex_mesh.get_face(result.face_id).get_points() + return true + + return false + + elif tool_state == ToolState.READY: + var offset:Vector2 = e.position - event_start.position + if offset.length_squared() > MathUtil.square(builder.drag_start_radius): + start_block_drag(viewport_camera_start, event_start) + + return true + + elif tool_state == ToolState.BLOCK_BASE: + + block_drag_cur = MathUtil.intersect_plane(origin_local, dir_local, block_drag_p0_local, drag_floor_normal) + + #print("block_drag_cur %s" % block_drag_cur) + + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + block_drag_cur = MathUtil.snap_to_grid(block_drag_cur, grid_step_size) + + #print("block_drag_cur snapped %s" % block_drag_cur) + + #Draw tool + var p01:Vector3 + var p10:Vector3 + if abs(drag_floor_normal.x) > abs(drag_floor_normal.y) and abs(drag_floor_normal.x) > abs(drag_floor_normal.z): + p01 = Vector3(block_drag_p0_local.x, block_drag_p0_local.y, block_drag_cur.z) + p10 = Vector3(block_drag_p0_local.x, block_drag_cur.y, block_drag_p0_local.z) + elif abs(drag_floor_normal.y) > abs(drag_floor_normal.z): + p01 = Vector3(block_drag_p0_local.x, block_drag_p0_local.y, block_drag_cur.z) + p10 = Vector3(block_drag_cur.x, block_drag_p0_local.y, block_drag_p0_local.z) + else: + p01 = Vector3(block_drag_p0_local.x, block_drag_cur.y, block_drag_p0_local.z) + p10 = Vector3(block_drag_cur.x, block_drag_p0_local.y, block_drag_p0_local.z) + + base_points = [block_drag_p0_local, p01, block_drag_cur, p10] + + return true + + elif tool_state == ToolState.BLOCK_HEIGHT: + block_drag_cur = MathUtil.closest_point_on_line(origin_local, dir_local, block_drag_p1_local, drag_floor_normal) + + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + block_drag_cur = MathUtil.snap_to_grid(block_drag_cur, grid_step_size) + + return true + + elif tool_state == ToolState.MOVE_BLOCK: + if e.alt_pressed: +# block_drag_cur = MathUtil.closest_point_on_line(origin_local, dir_local, block_drag_p0_local, drag_floor_normal) + block_drag_cur = MathUtil.closest_point_on_line(origin_local, dir_local, block_drag_p0_local, Vector3.UP) + else: +# block_drag_cur = MathUtil.intersect_plane(origin_local, dir_local, block_drag_p0_local, drag_floor_normal) + block_drag_cur = MathUtil.intersect_plane(origin_local, dir_local, block_drag_p0_local, Vector3.UP) + + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + block_drag_cur = MathUtil.snap_to_grid(block_drag_cur, grid_step_size) + + cmd_move_blocks.move_offset = block_drag_cur - block_drag_p0_local + cmd_move_blocks.do_it() + + return true + + elif tool_state == ToolState.MOVE_FACE: + var drag_to:Vector3 = MathUtil.closest_point_on_line(origin_local, dir_local, move_face_origin, cmd_move_face.move_dir_normal) + #print("move_face_origin %s norm %s" % [move_face_origin, cmd_move_face.move_dir_normal]) + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + drag_to = MathUtil.snap_to_grid(drag_to, grid_step_size) + + cmd_move_face.move_amount = (drag_to - move_face_origin).dot(cmd_move_face.move_dir_normal) + + cmd_move_face.do_it_intermediate() + + return true + + return super._gui_input(viewport_camera, event) + + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + builder.mode = CyclopsLevelBuilder.Mode.OBJECT + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + diff --git a/addons/cyclops_level_builder/tools/tool_clip.gd b/addons/cyclops_level_builder/tools/tool_clip.gd new file mode 100644 index 0000000..3b410fe --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_clip.gd @@ -0,0 +1,164 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends CyclopsTool +class_name ToolClip + +const TOOL_ID:String = "clip" + +enum ToolState { READY, PICK_POINTS, PICK_SIDE } +var tool_state:ToolState = ToolState.READY + +var clip_points:PackedVector3Array +var clip_normals:PackedVector3Array +var clip_block:CyclopsConvexBlock + +func _get_tool_id()->String: + return TOOL_ID + +func has_clip_point(point:Vector3)->bool: + for p in clip_points: + if p.is_equal_approx(point): + return true + return false + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + global_scene.draw_selected_blocks(viewport_camera) + + if !clip_points.is_empty(): + global_scene.draw_loop(clip_points, false, global_scene.tool_material) + global_scene.draw_points(clip_points, global_scene.tool_material) + + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var blocks_root:CyclopsBlocks = self.builder.active_node + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + #var global_scene:CyclopsGlobalScene = builder.get_node("/root/CyclopsAutoload") + + #_draw_tool(viewport_camera) + + if event is InputEventKey: + var e:InputEventKey = event + + if e.keycode == KEY_BACKSPACE: + if e.is_pressed(): + if !clip_points.is_empty(): + var count:int = clip_points.size() + clip_points.remove_at(count - 1) + clip_normals.remove_at(count - 1) + if clip_points.is_empty(): + clip_block = null + + return true + + elif e.keycode == KEY_ESCAPE: + clip_points.clear() + clip_normals.clear() + clip_block = null +# _draw_tool(viewport_camera) + return true + + elif e.keycode == KEY_ENTER: + #Cut at plane + var cut_plane:Plane + + if clip_points.size() == 3: + cut_plane = Plane(clip_points[0], clip_points[1], clip_points[2]) + elif clip_points.size() == 2: + var dir:Vector3 = clip_points[1] - clip_points[0] + var face_dir:Vector3 = clip_normals[0].cross(dir) + cut_plane = Plane(face_dir.normalized(), clip_points[0]) + else: + #Cannot cut with fewer than 2 points + return true + + var cmd:CommandClipBlock = CommandClipBlock.new() + cmd.builder = builder + cmd.blocks_root_path = blocks_root.get_path() + cmd.block_path = clip_block.get_path() + cmd.block_sibling_name = GeneralUtil.find_unique_name(blocks_root, "Block_") + cmd.cut_plane = cut_plane + cmd.material_path = builder.tool_material_path + cmd.uv_transform = builder.tool_uv_transform + + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo) + + #Clean up + clip_points.clear() + clip_normals.clear() + clip_block = null + +# _draw_tool(viewport_camera) + + return true + + if event is InputEventMouseButton: + + var e:InputEventMouseButton = event + + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return false + + if e.button_index == MOUSE_BUTTON_LEFT: + + if e.is_pressed(): + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var result:IntersectResults = blocks_root.intersect_ray_closest(origin, dir) + + if result: + var p:Vector3 = to_local(result.position, blocks_root.global_transform.inverse(), grid_step_size) + + if !has_clip_point(p): + if clip_points.is_empty(): + clip_block = result.object + + if clip_points.size() < 3: + clip_points.append(p) + clip_normals.append(result.normal) + else: + clip_points[2] = p + clip_normals[2] = result.normal + +# _draw_tool(viewport_camera) + + return true + + return false + + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + builder.mode = CyclopsLevelBuilder.Mode.OBJECT + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() diff --git a/addons/cyclops_level_builder/tools/tool_cylinder.gd b/addons/cyclops_level_builder/tools/tool_cylinder.gd new file mode 100644 index 0000000..c7c0bad --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_cylinder.gd @@ -0,0 +1,239 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends CyclopsTool +class_name ToolCylinder + +const TOOL_ID:String = "cylinder" + +enum ToolState { READY, FIRST_RING, SECOND_RING, DRAG_HEIGHT } +var tool_state:ToolState = ToolState.READY + +#@export var segments:int = 16 +#@export var tube:bool = false +var settings:ToolCylinderSettings = ToolCylinderSettings.new() + +var floor_normal:Vector3 +var base_center:Vector3 +var block_drag_cur:Vector3 +var drag_offset:Vector3 +var first_ring_radius:float +var second_ring_radius:float + + + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + builder.mode = CyclopsLevelBuilder.Mode.OBJECT + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + +func _get_tool_properties_editor()->Control: + var res_insp:ResourceInspector = preload("res://addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.tscn").instantiate() + + res_insp.target = settings + + return res_insp + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + global_scene.draw_selected_blocks(viewport_camera) + + if tool_state == ToolState.FIRST_RING: + var bounding_points:PackedVector3Array = MathUtil.create_circle_points(base_center, floor_normal, first_ring_radius, settings.segments) + global_scene.draw_loop(bounding_points, true, global_scene.tool_material) + global_scene.draw_points(bounding_points, global_scene.tool_material) + + elif tool_state == ToolState.SECOND_RING: + for radius in [first_ring_radius, second_ring_radius]: + var bounding_points:PackedVector3Array = MathUtil.create_circle_points(base_center, floor_normal, radius, settings.segments) + global_scene.draw_loop(bounding_points, true, global_scene.tool_material) + global_scene.draw_points(bounding_points, global_scene.tool_material) + + elif tool_state == ToolState.DRAG_HEIGHT: + var bounding_points:PackedVector3Array = MathUtil.create_circle_points(base_center, floor_normal, first_ring_radius, settings.segments) + global_scene.draw_prism(bounding_points, drag_offset, global_scene.tool_material) + + if settings.tube: + bounding_points = MathUtil.create_circle_points(base_center, floor_normal, second_ring_radius, settings.segments) + global_scene.draw_prism(bounding_points, drag_offset, global_scene.tool_material) + + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var blocks_root:CyclopsBlocks = self.builder.active_node + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + + if event is InputEventKey: + var e:InputEventKey = event + + if e.keycode == KEY_ESCAPE: + if e.is_pressed(): + tool_state = ToolState.READY + return true + + elif event is InputEventMouseButton: + + var e:InputEventMouseButton = event + if e.button_index == MOUSE_BUTTON_LEFT: + + if e.is_pressed(): + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + + if tool_state == ToolState.READY: + tool_state = ToolState.FIRST_RING + + first_ring_radius = 0 + second_ring_radius = 0 + + var result:IntersectResults = blocks_root.intersect_ray_closest(origin, dir) + if result: + #print("init base point block") + floor_normal = result.normal + + var p:Vector3 = to_local(result.position, blocks_root.global_transform.inverse(), grid_step_size) + base_center = p + + return true + + else: + #print("init base point empty space") + floor_normal = Vector3.UP + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + + var p:Vector3 = to_local(start_pos, blocks_root.global_transform.inverse(), grid_step_size) + base_center = p + + return true + else: + if tool_state == ToolState.FIRST_RING: + if settings.tube: + tool_state = ToolState.SECOND_RING + else: + tool_state = ToolState.DRAG_HEIGHT + return true + + elif tool_state == ToolState.SECOND_RING: + tool_state = ToolState.DRAG_HEIGHT + return true + + elif tool_state == ToolState.DRAG_HEIGHT: + #Create shape + + var cmd:CommandAddCylinder = CommandAddCylinder.new() + cmd.builder = builder + #cmd.block_name = GeneralUtil.find_unique_name(builder.active_node, "Block_") + cmd.block_name_prefix = "Block_" + cmd.blocks_root_path = blocks_root.get_path() + cmd.tube = settings.tube + cmd.origin = base_center + cmd.axis_normal = floor_normal + cmd.height = drag_offset.length() if drag_offset.dot(floor_normal) > 0 else - drag_offset.length() + if settings.tube: + cmd.radius_inner = min(first_ring_radius, second_ring_radius) + cmd.radius_outer = max(first_ring_radius, second_ring_radius) + else: + cmd.radius_inner = first_ring_radius + cmd.radius_outer = first_ring_radius + cmd.segments = settings.segments + cmd.uv_transform = builder.tool_uv_transform + cmd.material_path = builder.tool_material_path + + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + cmd.add_to_undo_manager(undo) + + tool_state = ToolState.READY + return true + + elif e.button_index == MOUSE_BUTTON_RIGHT: + if tool_state == ToolState.FIRST_RING || tool_state == ToolState.SECOND_RING || tool_state == ToolState.DRAG_HEIGHT: + if e.is_pressed(): + tool_state = ToolState.READY + return true + + elif e.button_index == MOUSE_BUTTON_WHEEL_UP: + if tool_state == ToolState.FIRST_RING || tool_state == ToolState.SECOND_RING || tool_state == ToolState.DRAG_HEIGHT: + if e.pressed: + settings.segments += 1 + return true + + elif e.button_index == MOUSE_BUTTON_WHEEL_DOWN: + if tool_state == ToolState.FIRST_RING || tool_state == ToolState.SECOND_RING || tool_state == ToolState.DRAG_HEIGHT: + if e.pressed: + settings.segments = max(settings.segments - 1, 3) + return true + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return false + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + if tool_state == ToolState.FIRST_RING: + var p_isect:Vector3 = MathUtil.intersect_plane(origin, dir, base_center, floor_normal) + var p_snapped = to_local(p_isect, blocks_root.global_transform.inverse(), grid_step_size) + first_ring_radius = (p_snapped - base_center).length() + + return true + + elif tool_state == ToolState.SECOND_RING: + var p_isect:Vector3 = MathUtil.intersect_plane(origin, dir, base_center, floor_normal) + var p_snapped = to_local(p_isect, blocks_root.global_transform.inverse(), grid_step_size) + second_ring_radius = (p_snapped - base_center).length() + + return true + + elif tool_state == ToolState.DRAG_HEIGHT: + block_drag_cur = MathUtil.closest_point_on_line(origin_local, dir_local, base_center, floor_normal) + + block_drag_cur = to_local(block_drag_cur, blocks_root.global_transform.inverse(), grid_step_size) + + drag_offset = block_drag_cur - base_center +# var bounding_points:PackedVector3Array = MathUtil.bounding_polygon_3d(base_points, floor_normal) + +# global_scene.clear_tool_mesh() +# global_scene.draw_prism(bounding_points, drag_offset, global_scene.tool_material) + + return true + + return super._gui_input(viewport_camera, event) + + diff --git a/addons/cyclops_level_builder/tools/tool_cylinder_settings.gd b/addons/cyclops_level_builder/tools/tool_cylinder_settings.gd new file mode 100644 index 0000000..5b66cd2 --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_cylinder_settings.gd @@ -0,0 +1,30 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Resource +class_name ToolCylinderSettings + +@export var segments:int = 16 +@export var tube:bool = false + diff --git a/addons/cyclops_level_builder/tools/tool_duplicate.gd b/addons/cyclops_level_builder/tools/tool_duplicate.gd new file mode 100644 index 0000000..ee36377 --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_duplicate.gd @@ -0,0 +1,136 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends CyclopsTool +class_name ToolDuplicate + +const TOOL_ID:String = "duplicate" + +var drag_start_point:Vector3 +var cmd_duplicate:CommandDuplicateBlocks + +enum ToolState { READY, DRAGGING, DONE } +var tool_state:ToolState = ToolState.READY + +func _get_tool_id()->String: + return TOOL_ID + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + global_scene.draw_selected_blocks(viewport_camera) + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var blocks_root:CyclopsBlocks = self.builder.active_node + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) +# var global_scene:CyclopsGlobalScene = builder.get_node("/root/CyclopsAutoload") + #_draw_tool(viewport_camera) + + if event is InputEventMouseButton: + + var e:InputEventMouseButton = event + if e.button_index == MOUSE_BUTTON_LEFT: + + if !e.is_pressed(): + if tool_state == ToolState.DRAGGING: + #print("committing duplicate") + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + if cmd_duplicate.will_change_anything(): + cmd_duplicate.add_to_undo_manager(undo) + + tool_state = ToolState.DONE + builder.switch_to_tool(ToolBlock.new()) + + return true + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return super._gui_input(viewport_camera, event) + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + if tool_state == ToolState.DRAGGING: + var drag_to:Vector3 + if e.alt_pressed: + drag_to = MathUtil.closest_point_on_line(origin_local, dir_local, drag_start_point, Vector3.UP) + else: + drag_to = MathUtil.intersect_plane(origin_local, dir_local, drag_start_point, Vector3.UP) + + var offset:Vector3 = drag_to - drag_start_point + offset = MathUtil.snap_to_grid(offset, grid_step_size) + + #print("duplicate drag by %s" % offset) + + cmd_duplicate.move_offset = offset + cmd_duplicate.do_it() + + return true + + + return false + + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + #builder.mode = CyclopsLevelBuilder.Mode.OBJECT + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + + #Invoke command immediately + cmd_duplicate = CommandDuplicateBlocks.new() + cmd_duplicate.builder = builder + var blocks_root:CyclopsBlocks = builder.active_node + cmd_duplicate.blocks_root_path = blocks_root.get_path() + var centroid:Vector3 + var count:int = 0 + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + cmd_duplicate.blocks_to_duplicate.append(block.get_path()) + centroid += block.control_mesh.bounds.get_center() + count += 1 + cmd_duplicate.lock_uvs = builder.lock_uvs + + centroid /= count + drag_start_point = centroid + tool_state = ToolState.DRAGGING + + cmd_duplicate.do_it() + + + diff --git a/addons/cyclops_level_builder/tools/tool_edit_base.gd b/addons/cyclops_level_builder/tools/tool_edit_base.gd new file mode 100644 index 0000000..6945938 --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_edit_base.gd @@ -0,0 +1,82 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends CyclopsTool +class_name ToolEditBase + +var mouse_hover_pos:Vector2 + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var blocks_root:CyclopsBlocks = self.builder.active_node + + if event is InputEventKey: + var e:InputEventKey = event + + if e.keycode == KEY_Q && e.alt_pressed: + if e.is_pressed(): + var origin:Vector3 = viewport_camera.project_ray_origin(mouse_hover_pos) + var dir:Vector3 = viewport_camera.project_ray_normal(mouse_hover_pos) + + var result:IntersectResults = blocks_root.intersect_ray_closest(origin, dir) + if result: + var cmd:CommandSelectBlocks = CommandSelectBlocks.new() + cmd.builder = builder + cmd.block_paths.append(result.object.get_path()) + + if cmd.will_change_anything(): + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo) + + _deactivate() + _activate(builder) + + pass + + return true + + + elif event is InputEventMouseButton: + var e:InputEventMouseButton = event + mouse_hover_pos = e.position + return false + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + mouse_hover_pos = e.position + return false + + return false + +func pick_material(global_scene:CyclopsGlobalScene, selected:bool = false, active = false)->Material: + if active: + return global_scene.tool_edit_active_material + if selected: + return global_scene.tool_edit_selected_material + return global_scene.tool_edit_unselected_material + + + diff --git a/addons/cyclops_level_builder/tools/tool_edit_edge.gd b/addons/cyclops_level_builder/tools/tool_edit_edge.gd new file mode 100644 index 0000000..f4c3285 --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_edit_edge.gd @@ -0,0 +1,321 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends ToolEditBase +class_name ToolEditEdge + +const TOOL_ID:String = "edit_edge" + +var handles:Array[HandleEdge] = [] + +enum ToolState { NONE, READY, DRAGGING } +var tool_state:ToolState = ToolState.NONE + +var drag_handle:HandleEdge +var drag_mouse_start_pos:Vector2 +var drag_handle_start_pos:Vector3 + +var tracked_blocks_root:CyclopsBlocks + +var cmd_move_edge:CommandMoveEdges + + +class PickHandleResult extends RefCounted: + var handle:HandleEdge + var position:Vector3 + + +func _get_tool_id()->String: + return TOOL_ID + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + + #var blocks_root:CyclopsBlocks = builder.active_node + for h in handles: + var block:CyclopsConvexBlock = builder.get_node(h.block_path) + var e:ConvexVolume.EdgeInfo = block.control_mesh.edges[h.edge_index] + var p0:Vector3 = block.control_mesh.vertices[e.start_index].point + var p1:Vector3 = block.control_mesh.vertices[e.end_index].point + + var active:bool = block.control_mesh.active_edge == h.edge_index + global_scene.draw_vertex((p0 + p1) / 2, pick_material(global_scene, e.selected, active)) + global_scene.draw_line(p0, p1, pick_material(global_scene, e.selected, active)) + +func setup_tool(): + handles = [] + + var blocks_root:CyclopsBlocks = builder.active_node + if blocks_root == null: + return + + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + for e_idx in block.control_mesh.edges.size(): + var ctl_mesh:ConvexVolume = block.control_mesh + var e:ConvexVolume.EdgeInfo = ctl_mesh.edges[e_idx] + + var handle:HandleEdge = HandleEdge.new() + handle.p_ref = ctl_mesh.vertices[e.start_index].point + handle.p_ref_init = handle.p_ref +# handle.p1 = ctl_mesh.vertices[e.end_index].point +# handle.p1_init = handle.p1 + handle.edge_index = e_idx + handle.block_path = block.get_path() + handles.append(handle) + + + #print("adding handle %s" % handle) + + +func pick_closest_handle(blocks_root:CyclopsBlocks, viewport_camera:Camera3D, position:Vector2, radius:float)->PickHandleResult: + var best_dist:float = INF + var best_handle:HandleEdge = null + var best_pick_position:Vector3 + + var pick_origin:Vector3 = viewport_camera.project_ray_origin(position) + var pick_dir:Vector3 = viewport_camera.project_ray_normal(position) + + for h in handles: + var block:CyclopsConvexBlock = builder.get_node(h.block_path) + var ctl_mesh:ConvexVolume = block.control_mesh + var edge:ConvexVolume.EdgeInfo = ctl_mesh.edges[h.edge_index] + + var p0 = ctl_mesh.vertices[edge.start_index].point + var p1 = ctl_mesh.vertices[edge.end_index].point + var p0_world:Vector3 = blocks_root.global_transform * p0 + var p1_world:Vector3 = blocks_root.global_transform * p1 + + var p0_screen:Vector2 = viewport_camera.unproject_position(p0_world) + var p1_screen:Vector2 = viewport_camera.unproject_position(p1_world) + + var dist_to_seg_2d_sq = MathUtil.dist_to_segment_squared_2d(position, p0_screen, p1_screen) + + if dist_to_seg_2d_sq > radius * radius: + #Failed handle radius test + continue + + var point_on_seg:Vector3 = MathUtil.closest_point_on_segment(pick_origin, pick_dir, p0_world, p1_world) + + var offset:Vector3 = point_on_seg - pick_origin + var parallel:Vector3 = offset.project(pick_dir) + var dist = parallel.dot(pick_dir) + if dist <= 0: + #Behind camera + continue + + #print("h pos %s ray orig %s ray dir %s offset %s para %s dist %s perp %s" % [h.position, ray_origin, ray_dir, offset, parallel, dist, perp]) + if dist >= best_dist: + continue + + best_pick_position = point_on_seg + best_dist = dist + best_handle = h + + if !best_handle: + return null + + var result:PickHandleResult = PickHandleResult.new() + result.handle = best_handle + result.position = best_pick_position + return result + +func active_node_changed(): + if tracked_blocks_root != null: + tracked_blocks_root.blocks_changed.disconnect(active_node_updated) + tracked_blocks_root = null + + setup_tool() +# draw_tool() + + tracked_blocks_root = builder.active_node + if tracked_blocks_root: + tracked_blocks_root.blocks_changed.connect(active_node_updated) + + +func active_node_updated(): + setup_tool() +# draw_tool() + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + builder.mode = CyclopsLevelBuilder.Mode.EDIT + builder.edit_mode = CyclopsLevelBuilder.EditMode.EDGE + builder.active_node_changed.connect(active_node_changed) + + tracked_blocks_root = builder.active_node + if tracked_blocks_root: + tracked_blocks_root.blocks_changed.connect(active_node_updated) + + + setup_tool() +# draw_tool() + + +func _deactivate(): + super._deactivate() + builder.active_node_changed.disconnect(active_node_changed) + if tracked_blocks_root != null: + tracked_blocks_root.blocks_changed.disconnect(active_node_updated) + + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var gui_result = super._gui_input(viewport_camera, event) + if gui_result: + return true + + var blocks_root:CyclopsBlocks = self.builder.active_node + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + #var global_scene:CyclopsGlobalScene = builder.get_node("/root/CyclopsAutoload") + #_draw_tool(viewport_camera) + +# if event is InputEventKey: +# return true + + if event is InputEventMouseButton: + + var e:InputEventMouseButton = event + if e.button_index == MOUSE_BUTTON_LEFT: + + if e.is_pressed(): + + if tool_state == ToolState.NONE: + drag_mouse_start_pos = e.position + tool_state = ToolState.READY + + return true + else: +# print("bn up: state %s" % tool_state) + if tool_state == ToolState.READY: + #print("cmd select") + var cmd:CommandSelectEdges = CommandSelectEdges.new() + cmd.builder = builder + + for child in builder.active_node.get_children(): + if child is CyclopsConvexBlock: + var cur_block:CyclopsConvexBlock = child + if cur_block.selected: + cmd.add_edges(cur_block.get_path(), []) + + cmd.selection_type = Selection.choose_type(e.shift_pressed, e.ctrl_pressed) + + var res:PickHandleResult = pick_closest_handle(blocks_root, viewport_camera, e.position, builder.handle_screen_radius) + if res: + var handle:HandleEdge = res.handle + + # print("handle %s" % handle) + + cmd.add_edge(handle.block_path, handle.edge_index) + #print("selectibg %s" % handle.vertex_index) + + if cmd.will_change_anything(): + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo) + + tool_state = ToolState.NONE +# draw_tool() + + elif tool_state == ToolState.DRAGGING: + #Finish drag + #print("cmd finish drag") + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + cmd_move_edge.add_to_undo_manager(undo) + + tool_state = ToolState.NONE + #setup_tool() + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return false + + if tool_state == ToolState.READY: + if e.position.distance_squared_to(drag_mouse_start_pos) > MathUtil.square(builder.drag_start_radius): + var res:PickHandleResult = pick_closest_handle(blocks_root, viewport_camera, drag_mouse_start_pos, builder.handle_screen_radius) + + if res: + var handle:HandleEdge = res.handle + drag_handle = handle +# drag_handle_start_pos = handle.p_ref + drag_handle_start_pos = res.position + tool_state = ToolState.DRAGGING + + cmd_move_edge = CommandMoveEdges.new() + cmd_move_edge.builder = builder +# cmd_move_vertex.block_path = handle.block_path +# cmd_move_vertex.vertex_position = handle.initial_position + + var handle_block:CyclopsConvexBlock = builder.get_node(handle.block_path) + if handle_block.control_mesh.edges[handle.edge_index].selected: + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + var vol:ConvexVolume = block.control_mesh + for e_idx in vol.edges.size(): + var edge:ConvexVolume.EdgeInfo = vol.edges[e_idx] + if edge.selected: + cmd_move_edge.add_edge(block.get_path(), e_idx) + else: + cmd_move_edge.add_edge(handle.block_path, handle.edge_index) + + + elif tool_state == ToolState.DRAGGING: + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + var drag_to:Vector3 + if e.alt_pressed: + drag_to = MathUtil.closest_point_on_line(origin_local, dir_local, drag_handle_start_pos, Vector3.UP) + else: + drag_to = MathUtil.intersect_plane(origin_local, dir_local, drag_handle_start_pos, Vector3.UP) + + var offset:Vector3 = drag_to - drag_handle_start_pos + offset = MathUtil.snap_to_grid(offset, grid_step_size) + drag_to = drag_handle_start_pos + offset + drag_handle.p_ref = drag_to +# drag_handle.p1 = drag_handle.p1_init + offset + + cmd_move_edge.move_offset = offset + cmd_move_edge.do_it() + +# draw_tool() + return true + + return false diff --git a/addons/cyclops_level_builder/tools/tool_edit_face.gd b/addons/cyclops_level_builder/tools/tool_edit_face.gd new file mode 100644 index 0000000..6d3e706 --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_edit_face.gd @@ -0,0 +1,342 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends ToolEditBase +class_name ToolEditFace + +const TOOL_ID:String = "edit_face" + +var handles:Array[HandleFace] = [] + +enum ToolState { NONE, READY, DRAGGING } +var tool_state:ToolState = ToolState.NONE + +var drag_handle:HandleFace +var drag_mouse_start_pos:Vector2 +var drag_handle_start_pos:Vector3 + +var tracked_blocks_root:CyclopsBlocks + +var cmd_move_face:CommandMoveFaces + + +class PickHandleResult extends RefCounted: + var handle:HandleFace + var position:Vector3 + +func _get_tool_id()->String: + return TOOL_ID + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + + var blocks_root:CyclopsBlocks = builder.active_node + for h in handles: +# print("draw face %s" % h) + var block:CyclopsConvexBlock = builder.get_node(h.block_path) + var f:ConvexVolume.FaceInfo = block.control_mesh.faces[h.face_index] + + var active:bool = block.control_mesh.active_face == h.face_index + global_scene.draw_vertex(h.p_ref, pick_material(global_scene, f.selected, active)) + + + if f.selected: + var edge_loop:PackedVector3Array = f.get_points() + for p_idx in edge_loop.size(): + edge_loop[p_idx] += f.normal * builder.tool_overlay_extrude + global_scene.draw_loop(edge_loop, true, pick_material(global_scene, f.selected, active)) + + var tris:PackedVector3Array = f.get_trianges() + for p_idx in tris.size(): + tris[p_idx] += f.normal * builder.tool_overlay_extrude + +# print("draw face %s %s %s" % [h.face_index, f.selected, f.active]) + var mat:Material = global_scene.tool_edit_active_fill_material if active else global_scene.tool_edit_selected_fill_material + global_scene.draw_triangles(tris, mat) + + +func setup_tool(): + handles = [] + + var blocks_root:CyclopsBlocks = builder.active_node + if blocks_root == null: + return +# var grid_step_size:float = pow(2, blocks_root.grid_size) + + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + for f_idx in block.control_mesh.faces.size(): +# print("adding face hande %s %s" % [block.name, f_idx]) + + var ctl_mesh:ConvexVolume = block.control_mesh + var face:ConvexVolume.FaceInfo = ctl_mesh.faces[f_idx] + + var handle:HandleFace = HandleFace.new() + + var p_start:Vector3 = face.get_centroid() +# p_start = MathUtil.snap_to_grid(p_start, grid_step_size) + handle.p_ref = p_start + handle.p_ref_init = p_start + + handle.face_index = f_idx + handle.face_id = face.id + handle.block_path = block.get_path() + handles.append(handle) + + + #print("adding handle %s" % handle) + +func pick_closest_handle(viewport_camera:Camera3D, position:Vector2, radius:float)->PickHandleResult: + var blocks_root:CyclopsBlocks = builder.active_node + if blocks_root == null: + return + + var pick_origin:Vector3 = viewport_camera.project_ray_origin(position) + var pick_dir:Vector3 = viewport_camera.project_ray_normal(position) + + if builder.display_mode == DisplayMode.Type.TEXTURED: + var result:IntersectResults = blocks_root.intersect_ray_closest_selected_only(pick_origin, pick_dir) + if result: + for h in handles: + if h.block_path == result.object.get_path() && h.face_id == result.face_id: + var ret:PickHandleResult = PickHandleResult.new() + ret.handle = h + ret.position = result.position + return ret + + elif builder.display_mode == DisplayMode.Type.WIRE: + var best_dist:float = INF + var best_handle:HandleFace = null + var best_position:Vector3 + + + for h in handles: + var h_world_pos:Vector3 = blocks_root.global_transform * h.p_ref + var h_screen_pos:Vector2 = viewport_camera.unproject_position(h_world_pos) + if position.distance_squared_to(h_screen_pos) > radius * radius: + #Failed handle radius test + continue + + var offset:Vector3 = h_world_pos - pick_origin + var parallel:Vector3 = offset.project(pick_dir) + var dist = parallel.dot(pick_dir) + if dist <= 0: + #Behind camera + continue + + #print("h pos %s ray orig %s ray dir %s offset %s para %s dist %s perp %s" % [h.position, ray_origin, ray_dir, offset, parallel, dist, perp]) + if dist >= best_dist: + continue + + best_dist = dist + best_handle = h + best_position = h_world_pos + + var result:PickHandleResult = PickHandleResult.new() + result.handle = best_handle + result.position = best_position + return result + + return null + + + +func active_node_changed(): + if tracked_blocks_root != null: + tracked_blocks_root.blocks_changed.disconnect(active_node_updated) + tracked_blocks_root = null + + setup_tool() + #draw_tool() + + tracked_blocks_root = builder.active_node + if tracked_blocks_root: + tracked_blocks_root.blocks_changed.connect(active_node_updated) + + + +func active_node_updated(): + setup_tool() + #draw_tool() + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + builder.mode = CyclopsLevelBuilder.Mode.EDIT + builder.edit_mode = CyclopsLevelBuilder.EditMode.FACE + builder.active_node_changed.connect(active_node_changed) + + tracked_blocks_root = builder.active_node + if tracked_blocks_root: + tracked_blocks_root.blocks_changed.connect(active_node_updated) + + + setup_tool() + #draw_tool() + + +func _deactivate(): + super._deactivate() + builder.active_node_changed.disconnect(active_node_changed) + if tracked_blocks_root != null: + tracked_blocks_root.blocks_changed.disconnect(active_node_updated) + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var gui_result = super._gui_input(viewport_camera, event) + if gui_result: + return true + + var blocks_root:CyclopsBlocks = self.builder.active_node + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) +# var global_scene:CyclopsGlobalScene = builder.get_node("/root/CyclopsAutoload") + #_draw_tool(viewport_camera) + +# if event is InputEventKey: +# return true + + if event is InputEventMouseButton: + + var e:InputEventMouseButton = event + if e.button_index == MOUSE_BUTTON_LEFT: + + if e.is_pressed(): + + if tool_state == ToolState.NONE: + drag_mouse_start_pos = e.position + tool_state = ToolState.READY + + return true + else: +# print("bn up: state %s" % tool_state) + if tool_state == ToolState.READY: + #print("cmd select") + + var cmd:CommandSelectFaces = CommandSelectFaces.new() + cmd.builder = builder + + for child in builder.active_node.get_children(): + if child is CyclopsConvexBlock: + var cur_block:CyclopsConvexBlock = child + if cur_block.selected: + cmd.add_faces(cur_block.get_path(), []) + + var res:PickHandleResult = pick_closest_handle(viewport_camera, e.position, builder.handle_screen_radius) + if res: + var handle:HandleFace = res.handle + #print("handle %s" % handle) + + cmd.add_face(handle.block_path, handle.face_index) + #print("selecting %s" % handle.face_index) + + cmd.selection_type = Selection.choose_type(e.shift_pressed, e.ctrl_pressed) + + if cmd.will_change_anything(): + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo) + + + tool_state = ToolState.NONE +# draw_tool() + + elif tool_state == ToolState.DRAGGING: + #Finish drag + #print("cmd finish drag") + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + cmd_move_face.add_to_undo_manager(undo) + + tool_state = ToolState.NONE + + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return false + + if tool_state == ToolState.READY: + if e.position.distance_squared_to(drag_mouse_start_pos) > MathUtil.square(builder.drag_start_radius): + var res:PickHandleResult = pick_closest_handle(viewport_camera, drag_mouse_start_pos, builder.handle_screen_radius) + + if res: + var handle:HandleFace = res.handle + drag_handle = handle +# drag_handle_start_pos = handle.p_ref + drag_handle_start_pos = res.position + tool_state = ToolState.DRAGGING + + cmd_move_face = CommandMoveFaces.new() + cmd_move_face.builder = builder + + var handle_block:CyclopsConvexBlock = builder.get_node(handle.block_path) + if handle_block.control_mesh.faces[handle.face_index].selected: + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + var vol:ConvexVolume = block.control_mesh + for f_idx in vol.faces.size(): + var face:ConvexVolume.FaceInfo = vol.faces[f_idx] + if face.selected: + cmd_move_face.add_face(block.get_path(), f_idx) + else: + cmd_move_face.add_face(handle.block_path, handle.face_index) + + + elif tool_state == ToolState.DRAGGING: + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + var drag_to:Vector3 + if e.alt_pressed: + drag_to = MathUtil.closest_point_on_line(origin_local, dir_local, drag_handle_start_pos, Vector3.UP) + else: + drag_to = MathUtil.intersect_plane(origin_local, dir_local, drag_handle_start_pos, Vector3.UP) + + var offset = drag_to - drag_handle_start_pos + offset = MathUtil.snap_to_grid(offset, grid_step_size) + drag_to = drag_handle_start_pos + offset + drag_handle.p_ref = drag_to + + cmd_move_face.move_offset = offset +# print("drag_offset %s" % cmd_move_face.move_offset) + cmd_move_face.do_it() + +# draw_tool() + return true + + return false + diff --git a/addons/cyclops_level_builder/tools/tool_edit_vertex.gd b/addons/cyclops_level_builder/tools/tool_edit_vertex.gd new file mode 100644 index 0000000..742b5b4 --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_edit_vertex.gd @@ -0,0 +1,332 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends ToolEditBase +class_name ToolEditVertex + +const TOOL_ID:String = "edit_vertex" + +var handles:Array[HandleVertex] = [] + +enum ToolState { NONE, READY, DRAGGING, DRAGGING_ADD } +var tool_state:ToolState = ToolState.NONE + +#var mouse_hover_pos:Vector2 + +var drag_handle:HandleVertex +var drag_mouse_start_pos:Vector2 +var drag_handle_start_pos:Vector3 +var added_point_pos:Vector3 + +var cmd_move_vertex:CommandMoveVertices +var cmd_add_vertex:CommandAddVertices + +var tracked_blocks_root:CyclopsBlocks + +func _get_tool_id()->String: + return TOOL_ID + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + + #var blocks_root:CyclopsBlocks = builder.active_node + for h in handles: + var block:CyclopsConvexBlock = builder.get_node(h.block_path) + var v:ConvexVolume.VertexInfo = block.control_mesh.vertices[h.vertex_index] + + #print("draw vert %s %s" % [h.vertex_index, v.selected]) + var active:bool = block.control_mesh.active_vertex == h.vertex_index + global_scene.draw_vertex(h.position, pick_material(global_scene, v.selected, active)) + +func setup_tool(): + handles = [] +# print("setup_tool") + + var blocks_root:CyclopsBlocks = builder.active_node + if blocks_root == null: + return + + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: +# print("block sel %s" % block.block_data.vertex_selected) + + for v_idx in block.control_mesh.vertices.size(): + var v:ConvexVolume.VertexInfo = block.control_mesh.vertices[v_idx] + var handle:HandleVertex = HandleVertex.new() + handle.position = v.point + handle.vertex_index = v_idx + handle.initial_position = v.point + handle.block_path = block.get_path() + handles.append(handle) + + #print("adding handle %s" % handle) + + +func pick_closest_handle(blocks_root:CyclopsBlocks, viewport_camera:Camera3D, position:Vector2, radius:float)->HandleVertex: + var best_dist:float = INF + var best_handle:HandleVertex = null + + var origin:Vector3 = viewport_camera.project_ray_origin(position) + var dir:Vector3 = viewport_camera.project_ray_normal(position) + + for h in handles: + var h_world_pos:Vector3 = blocks_root.global_transform * h.position + var h_screen_pos:Vector2 = viewport_camera.unproject_position(h_world_pos) + if position.distance_squared_to(h_screen_pos) > radius * radius: + #Failed handle radius test + continue + + var offset:Vector3 = h_world_pos - origin + var parallel:Vector3 = offset.project(dir) + var dist = parallel.dot(dir) + if dist <= 0: + #Behind camera + continue + + #print("h pos %s ray orig %s ray dir %s offset %s para %s dist %s perp %s" % [h.position, ray_origin, ray_dir, offset, parallel, dist, perp]) + if dist >= best_dist: + continue + + best_dist = dist + best_handle = h + + return best_handle + +func active_node_changed(): + if tracked_blocks_root != null: + tracked_blocks_root.blocks_changed.disconnect(active_node_updated) + tracked_blocks_root = null + + setup_tool() + + tracked_blocks_root = builder.active_node + if tracked_blocks_root: + tracked_blocks_root.blocks_changed.connect(active_node_updated) + + + +func active_node_updated(): + setup_tool() + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + builder.mode = CyclopsLevelBuilder.Mode.EDIT + builder.edit_mode = CyclopsLevelBuilder.EditMode.VERTEX + builder.active_node_changed.connect(active_node_changed) + + tracked_blocks_root = builder.active_node + if tracked_blocks_root: + tracked_blocks_root.blocks_changed.connect(active_node_updated) + + setup_tool() + + +func _deactivate(): + super._deactivate() + builder.active_node_changed.disconnect(active_node_changed) + if tracked_blocks_root != null: + tracked_blocks_root.blocks_changed.disconnect(active_node_updated) + + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var gui_result = super._gui_input(viewport_camera, event) + if gui_result: + return true + + var blocks_root:CyclopsBlocks = self.builder.active_node + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + + if event is InputEventMouseButton: + + var e:InputEventMouseButton = event + if e.button_index == MOUSE_BUTTON_LEFT: + + if e.is_pressed(): + + if tool_state == ToolState.NONE: + drag_mouse_start_pos = e.position + tool_state = ToolState.READY + + return true + else: + if tool_state == ToolState.READY: + #print("cmd select") + var handle:HandleVertex = pick_closest_handle(blocks_root, viewport_camera, drag_mouse_start_pos, builder.handle_screen_radius) + + var cmd:CommandSelectVertices = CommandSelectVertices.new() + cmd.builder = builder + + for child in builder.active_node.get_children(): + if child is CyclopsConvexBlock: + var cur_block:CyclopsConvexBlock = child + if cur_block.selected: + cmd.add_vertices(cur_block.get_path(), []) + + cmd.selection_type = Selection.choose_type(e.shift_pressed, e.ctrl_pressed) + + if handle: + cmd.add_vertex(handle.block_path, handle.vertex_index) + #print("selectibg %s" % handle.vertex_index) + + if cmd.will_change_anything(): + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + cmd.add_to_undo_manager(undo) + + + tool_state = ToolState.NONE + cmd_move_vertex = null + + elif tool_state == ToolState.DRAGGING: + #Finish drag + #print("cmd finish drag") + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + cmd_move_vertex.add_to_undo_manager(undo) + + tool_state = ToolState.NONE + + elif tool_state == ToolState.DRAGGING_ADD: + #Finish drag + #print("cmd finish drag add") + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + cmd_add_vertex.add_to_undo_manager(undo) + + tool_state = ToolState.NONE + cmd_add_vertex = null + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + #mouse_hover_pos = e.position + + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return false + + if tool_state == ToolState.READY: + if e.position.distance_squared_to(drag_mouse_start_pos) > MathUtil.square(builder.drag_start_radius): + var handle:HandleVertex = pick_closest_handle(blocks_root, viewport_camera, drag_mouse_start_pos, builder.handle_screen_radius) + + if handle: + drag_handle = handle + drag_handle_start_pos = handle.position + tool_state = ToolState.DRAGGING + + cmd_move_vertex = CommandMoveVertices.new() + cmd_move_vertex.builder = builder + + var handle_block:CyclopsConvexBlock = builder.get_node(handle.block_path) + if handle_block.control_mesh.vertices[handle.vertex_index].selected: + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + var vol:ConvexVolume = block.control_mesh + for v_idx in vol.vertices.size(): + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + if v.selected: + cmd_move_vertex.add_vertex(block.get_path(), v_idx) + else: + cmd_move_vertex.add_vertex(handle.block_path, handle.vertex_index) + + return true + + else: + if e.ctrl_pressed: + var pick_origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var pick_dir:Vector3 = viewport_camera.project_ray_normal(e.position) + var result:IntersectResults = blocks_root.intersect_ray_closest_selected_only(pick_origin, pick_dir) + if result: + #print("start drag add") + drag_handle_start_pos = result.position + added_point_pos = result.position + tool_state = ToolState.DRAGGING_ADD + + cmd_add_vertex = CommandAddVertices.new() + cmd_add_vertex.builder = builder + + cmd_add_vertex.block_path = result.object.get_path() + cmd_add_vertex.points_to_add = [added_point_pos] + #print("init point %s" % added_point_pos) + + return true + + elif tool_state == ToolState.DRAGGING: + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + var drag_to:Vector3 + if e.alt_pressed: + drag_to = MathUtil.closest_point_on_line(origin_local, dir_local, drag_handle_start_pos, Vector3.UP) + else: + drag_to = MathUtil.intersect_plane(origin_local, dir_local, drag_handle_start_pos, Vector3.UP) + + drag_to = MathUtil.snap_to_grid(drag_to, grid_step_size) + drag_handle.position = drag_to + + cmd_move_vertex.move_offset = drag_to - drag_handle.initial_position + cmd_move_vertex.do_it() + +# draw_tool() + return true + + elif tool_state == ToolState.DRAGGING_ADD: + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + var drag_to:Vector3 + if e.alt_pressed: + drag_to = MathUtil.closest_point_on_line(origin_local, dir_local, drag_handle_start_pos, Vector3.UP) + else: + drag_to = MathUtil.intersect_plane(origin_local, dir_local, drag_handle_start_pos, Vector3.UP) + + drag_to = MathUtil.snap_to_grid(drag_to, grid_step_size) + + added_point_pos = drag_to + #print("drag point to %s" % drag_to) + + cmd_add_vertex.points_to_add = [drag_to] + cmd_add_vertex.do_it() + + return false + diff --git a/addons/cyclops_level_builder/tools/tool_prism.gd b/addons/cyclops_level_builder/tools/tool_prism.gd new file mode 100644 index 0000000..be7a760 --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_prism.gd @@ -0,0 +1,213 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends CyclopsTool +class_name ToolPrism + +const TOOL_ID:String = "prism" + +enum ToolState { READY, BASE_POINTS, DRAG_HEIGHT } +var tool_state:ToolState = ToolState.READY + +var floor_normal:Vector3 +var base_points:PackedVector3Array +var block_drag_cur:Vector3 +var drag_offset:Vector3 +var preview_point:Vector3 + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + builder.mode = CyclopsLevelBuilder.Mode.OBJECT + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + global_scene.draw_selected_blocks(viewport_camera) + + if tool_state == ToolState.BASE_POINTS: + var bounding_points:PackedVector3Array = MathUtil.bounding_polygon_3d(base_points, floor_normal) + global_scene.draw_loop(bounding_points, true, global_scene.tool_material) + global_scene.draw_points(bounding_points, global_scene.tool_material) + + global_scene.draw_vertex(preview_point, global_scene.tool_material) + + if tool_state == ToolState.DRAG_HEIGHT: + var bounding_points:PackedVector3Array = MathUtil.bounding_polygon_3d(base_points, floor_normal) + global_scene.draw_prism(bounding_points, drag_offset, global_scene.tool_material) + + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var blocks_root:CyclopsBlocks = self.builder.active_node + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + + if event is InputEventKey: + var e:InputEventKey = event + + if e.keycode == KEY_ENTER: + if e.is_pressed(): + if tool_state == ToolState.BASE_POINTS: + drag_offset = Vector3.ZERO + tool_state = ToolState.DRAG_HEIGHT + return true + + elif e.keycode == KEY_BACKSPACE: + if e.is_pressed(): + base_points.remove_at(base_points.size() - 1) + return true + + elif e.keycode == KEY_ESCAPE: + if e.is_pressed(): + tool_state = ToolState.READY + return true + + elif event is InputEventMouseButton: + + var e:InputEventMouseButton = event + if e.button_index == MOUSE_BUTTON_LEFT: + + if e.is_pressed(): + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + if tool_state == ToolState.READY: + base_points.clear() + tool_state = ToolState.BASE_POINTS + + var result:IntersectResults = blocks_root.intersect_ray_closest(origin, dir) + if result: + #print("init base point block") + floor_normal = result.normal + + var p:Vector3 = to_local(result.position, blocks_root.global_transform.inverse(), grid_step_size) +# + base_points.append(p) + preview_point = p + + return true + + else: + #print("init base point empty space") + floor_normal = Vector3.UP + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + + var p:Vector3 = to_local(start_pos, blocks_root.global_transform.inverse(), grid_step_size) + base_points.append(p) + + return true + + elif tool_state == ToolState.BASE_POINTS: + #print("add base point") + if e.double_click: + if e.is_pressed(): + drag_offset = Vector3.ZERO + tool_state = ToolState.DRAG_HEIGHT + return true + + var p_isect:Vector3 = MathUtil.intersect_plane(origin, dir, base_points[0], floor_normal) + var p:Vector3 = to_local(p_isect, blocks_root.global_transform.inverse(), grid_step_size) + base_points.append(p) + + var bounding_points:PackedVector3Array = MathUtil.bounding_polygon_3d(base_points, floor_normal) + return true + + elif tool_state == ToolState.DRAG_HEIGHT: + var bounding_points:PackedVector3Array = MathUtil.bounding_polygon_3d(base_points, floor_normal) + drag_offset = block_drag_cur - base_points[0] + #drag_offset = Vector3.ZERO + + var cmd:CommandAddPrism = CommandAddPrism.new() + cmd.builder = builder + cmd.block_name = GeneralUtil.find_unique_name(builder.active_node, "Block_") + cmd.blocks_root_path = blocks_root.get_path() +# command.block_owner = builder.get_editor_interface().get_edited_scene_root() + cmd.base_polygon = bounding_points + cmd.extrude = drag_offset + cmd.uv_transform = builder.tool_uv_transform + cmd.material_path = builder.tool_material_path + + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + cmd.add_to_undo_manager(undo) + +# global_scene.clear_tool_mesh() +# global_scene.draw_selected_blocks(viewport_camera) + + tool_state = ToolState.READY + return true + + if e.button_index == MOUSE_BUTTON_RIGHT: + + if tool_state == ToolState.BASE_POINTS: + if e.is_pressed(): + for p_idx in base_points.size(): + var screem_pos:Vector2 = viewport_camera.unproject_position(base_points[p_idx]) + if screem_pos.distance_to(e.position) < builder.handle_screen_radius: + base_points.remove_at(p_idx) + break + return true + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return false + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + if tool_state == ToolState.BASE_POINTS: + var p_isect:Vector3 = MathUtil.intersect_plane(origin, dir, base_points[0], floor_normal) + preview_point = to_local(p_isect, blocks_root.global_transform.inverse(), grid_step_size) + + + elif tool_state == ToolState.DRAG_HEIGHT: + block_drag_cur = MathUtil.closest_point_on_line(origin_local, dir_local, base_points[0], floor_normal) + + block_drag_cur = to_local(block_drag_cur, blocks_root.global_transform.inverse(), grid_step_size) + + drag_offset = block_drag_cur - base_points[0] + var bounding_points:PackedVector3Array = MathUtil.bounding_polygon_3d(base_points, floor_normal) + +# global_scene.clear_tool_mesh() +# global_scene.draw_prism(bounding_points, drag_offset, global_scene.tool_material) + + return true + + return super._gui_input(viewport_camera, event) + + diff --git a/addons/cyclops_level_builder/tools/tool_stairs.gd b/addons/cyclops_level_builder/tools/tool_stairs.gd new file mode 100644 index 0000000..e151634 --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_stairs.gd @@ -0,0 +1,272 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends CyclopsTool +class_name ToolStairs + +const TOOL_ID:String = "stairs" + +enum ToolState { READY, DRAG_BASE, DRAG_HEIGHT } +var tool_state:ToolState = ToolState.READY + +var settings:ToolStairsSettings = ToolStairsSettings.new() + +var floor_normal:Vector3 +var drag_origin:Vector3 +var base_drag_cur:Vector3 +var block_drag_cur:Vector3 + + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + builder.mode = CyclopsLevelBuilder.Mode.OBJECT + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + +func _get_tool_properties_editor()->Control: + var res_insp:ResourceInspector = preload("res://addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.tscn").instantiate() + + res_insp.target = settings + + return res_insp + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + global_scene.draw_selected_blocks(viewport_camera) + + + if tool_state == ToolState.DRAG_BASE: + var p01:Vector3 + var p10:Vector3 + var axis:MathUtil.Axis = MathUtil.get_longest_axis(floor_normal) + match axis: + MathUtil.Axis.X: + p01 = Vector3(drag_origin.x, drag_origin.y, base_drag_cur.z) + p10 = Vector3(drag_origin.x, base_drag_cur.y, drag_origin.z) + MathUtil.Axis.Y: + p01 = Vector3(drag_origin.x, drag_origin.y, base_drag_cur.z) + p10 = Vector3(base_drag_cur.x, drag_origin.y, drag_origin.z) + MathUtil.Axis.Z: + p01 = Vector3(drag_origin.x, base_drag_cur.y, drag_origin.z) + p10 = Vector3(base_drag_cur.x, drag_origin.y, drag_origin.z) + + var base_points:PackedVector3Array = [drag_origin, p01, base_drag_cur, p10] + + global_scene.draw_loop(base_points, true, global_scene.tool_material) + global_scene.draw_points(base_points, global_scene.tool_material) + + if tool_state == ToolState.DRAG_HEIGHT: + var tan_bi:Array[Vector3] = MathUtil.get_axis_aligned_tangent_and_binormal(floor_normal) + var u_normal:Vector3 = tan_bi[0] + var v_normal:Vector3 = tan_bi[1] + + #Rotate ccw by 90 degree increments + match settings.direction: + 1: + var tmp:Vector3 = u_normal + u_normal = -v_normal + v_normal = tmp + 2: + u_normal = -u_normal + v_normal = -v_normal + 3: + var tmp:Vector3 = -u_normal + u_normal = v_normal + v_normal = tmp + + var u_span:Vector3 = (base_drag_cur - drag_origin).project(u_normal) + var v_span:Vector3 = (base_drag_cur - drag_origin).project(v_normal) + + var stairs_origin:Vector3 = drag_origin + if u_span.dot(u_normal) < 0: + stairs_origin += u_span + u_span = -u_span + if v_span.dot(v_normal) < 0: + stairs_origin += v_span + v_span = -v_span + + #Stairs should ascend along v axis + global_scene.draw_cube(drag_origin, base_drag_cur, block_drag_cur, global_scene.tool_material) + + var height_offset = block_drag_cur - base_drag_cur + if height_offset.dot(floor_normal) < 0: + return + var num_steps:int = min(v_span.length() / settings.step_depth, height_offset.length() / settings.step_height) + + var max_height:float = floor(height_offset.length() / settings.step_height) * settings.step_height + + var step_span:Vector3 = v_normal * settings.step_depth + for i in num_steps: + var base_points:PackedVector3Array = [stairs_origin + step_span * i, \ + stairs_origin + u_span + step_span * i, \ + stairs_origin + u_span + step_span * (i + 1), \ + stairs_origin + step_span * (i + 1)] + global_scene.draw_prism(base_points, \ + floor_normal * (max_height - settings.step_height * i), \ + global_scene.tool_material) + + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var blocks_root:CyclopsBlocks = self.builder.active_node + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + + if event is InputEventMouseButton: + + var e:InputEventMouseButton = event + if e.button_index == MOUSE_BUTTON_LEFT: + + if e.is_pressed(): + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + if tool_state == ToolState.READY: + tool_state = ToolState.DRAG_BASE + + + var result:IntersectResults = blocks_root.intersect_ray_closest(origin, dir) + if result: + #print("init base point block") + floor_normal = result.normal + + var p:Vector3 = to_local(result.position, blocks_root.global_transform.inverse(), grid_step_size) + drag_origin = p + base_drag_cur = p + + return true + + else: + #print("init base point empty space") + floor_normal = Vector3.UP + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + + var p:Vector3 = to_local(start_pos, blocks_root.global_transform.inverse(), grid_step_size) + drag_origin = p + base_drag_cur = p + + return true + + else: + if tool_state == ToolState.DRAG_BASE: + tool_state = ToolState.DRAG_HEIGHT + block_drag_cur = base_drag_cur + return true + + elif tool_state == ToolState.DRAG_HEIGHT: + #Create shape + + var cmd:CommandAddStairs = CommandAddStairs.new() + cmd.builder = builder + cmd.blocks_root_path = blocks_root.get_path() + cmd.block_name_prefix = "Block_" + cmd.floor_normal = floor_normal + cmd.drag_origin = drag_origin + cmd.base_drag_cur = base_drag_cur + cmd.block_drag_cur = block_drag_cur + cmd.step_height = settings.step_height + cmd.step_depth = settings.step_depth + cmd.direction = settings.direction + cmd.uv_transform = builder.tool_uv_transform + cmd.material_path = builder.tool_material_path + + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + cmd.add_to_undo_manager(undo) + + tool_state = ToolState.READY + return true + + elif e.button_index == MOUSE_BUTTON_RIGHT: + if tool_state == ToolState.DRAG_BASE || tool_state == ToolState.DRAG_HEIGHT: + if e.is_pressed(): + tool_state = ToolState.READY + return true + + elif e.button_index == MOUSE_BUTTON_WHEEL_UP: + if tool_state == ToolState.DRAG_BASE || tool_state == ToolState.DRAG_HEIGHT: + if e.pressed: + if e.ctrl_pressed: + if e.shift_pressed: + var size = log(settings.step_depth) / log(2) + settings.step_depth = pow(2, size + 1) + else: + var size = log(settings.step_height) / log(2) + settings.step_height = pow(2, size + 1) + else: + settings.direction = wrap(settings.direction + 1, 0, 4) + return true + + elif e.button_index == MOUSE_BUTTON_WHEEL_DOWN: + if tool_state == ToolState.DRAG_BASE || tool_state == ToolState.DRAG_HEIGHT: + if e.pressed: + if e.ctrl_pressed: + if e.shift_pressed: + var size = log(settings.step_depth) / log(2) + settings.step_depth = pow(2, size - 1) + else: + var size = log(settings.step_height) / log(2) + settings.step_height = pow(2, size - 1) + else: + settings.direction = wrap(settings.direction - 1, 0, 4) + return true + + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return false + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + if tool_state == ToolState.DRAG_BASE: + var p_isect:Vector3 = MathUtil.intersect_plane(origin, dir, drag_origin, floor_normal) + var p_snapped = to_local(p_isect, blocks_root.global_transform.inverse(), grid_step_size) + base_drag_cur = p_snapped + + return true + + elif tool_state == ToolState.DRAG_HEIGHT: + block_drag_cur = MathUtil.closest_point_on_line(origin_local, dir_local, base_drag_cur, floor_normal) + + block_drag_cur = to_local(block_drag_cur, blocks_root.global_transform.inverse(), grid_step_size) + +# drag_offset = block_drag_cur - base_drag_cur + + return true + + return super._gui_input(viewport_camera, event) + diff --git a/addons/cyclops_level_builder/tools/tool_stairs_settings.gd b/addons/cyclops_level_builder/tools/tool_stairs_settings.gd new file mode 100644 index 0000000..d3cba0d --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_stairs_settings.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Resource +class_name ToolStairsSettings + +@export var step_height:float = .25 +@export var step_depth:float = .5 +@export var direction:int = 0 + diff --git a/addons/cyclops_level_builder/util/display_mode.gd b/addons/cyclops_level_builder/util/display_mode.gd new file mode 100644 index 0000000..5ef137d --- /dev/null +++ b/addons/cyclops_level_builder/util/display_mode.gd @@ -0,0 +1,28 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name DisplayMode + +enum Type { WIRE, TEXTURED } + diff --git a/addons/cyclops_level_builder/util/general_util.gd b/addons/cyclops_level_builder/util/general_util.gd new file mode 100644 index 0000000..f74a2ee --- /dev/null +++ b/addons/cyclops_level_builder/util/general_util.gd @@ -0,0 +1,60 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name GeneralUtil + +static func find_unique_name(parent:Node, base_name:String)->String: + #Check if numeric suffix already exists + var regex = RegEx.new() + regex.compile("(\\d+)") + var match_res:RegExMatch = regex.search(base_name) + + var name_idx:int = 0 + + if match_res: + var suffix:String = match_res.get_string(1) + name_idx = int(suffix) + 1 + base_name = base_name.substr(0, base_name.length() - suffix.length()) + + #Search for free index + while true: + var name = base_name + str(name_idx) + if !parent.find_child(name, false): + return name + + name_idx += 1 + + return "" + +static func format_planes_string(planes:Array[Plane])->String: + var result:String = "" + for p in planes: + result = result + "(%s, %s, %s, %s)," % [p.x, p.y, p.z, p.d] + return result + + +static func dump_properties(obj): + for prop in obj.get_property_list(): + var name:String = prop["name"] + print ("%s: %s" % [name, str(obj.get(name))]) diff --git a/addons/cyclops_level_builder/util/selection.gd b/addons/cyclops_level_builder/util/selection.gd new file mode 100644 index 0000000..46e40e3 --- /dev/null +++ b/addons/cyclops_level_builder/util/selection.gd @@ -0,0 +1,37 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +class_name Selection + +enum Type { REPLACE, ADD, SUBTRACT, TOGGLE } + +static func choose_type(shift_pressed:bool, ctrl_pressed)->Type: + if !shift_pressed and !ctrl_pressed: + return Type.REPLACE + elif shift_pressed and !ctrl_pressed: + return Type.TOGGLE + elif !shift_pressed and ctrl_pressed: + return Type.ADD + else: + return Type.SUBTRACT diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..adc26df --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..34e83e7 --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b2rfviw5fuem4" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..2cb3cfe --- /dev/null +++ b/project.godot @@ -0,0 +1,15 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="quack" +config/features=PackedStringArray("4.0", "Forward Plus") +config/icon="res://icon.svg"