From 3a9fa29ca2671d72144f92749a72b38021def001 Mon Sep 17 00:00:00 2001 From: Holly Date: Thu, 24 Apr 2025 09:11:42 +0100 Subject: [PATCH] Initial Commit --- icon.svg | 1 + icon.svg.import | 37 +++++++++++ node_3d.gd | 30 +++++++++ node_3d.gd.uid | 1 + node_3d.tscn | 56 +++++++++++++++++ project.godot | 16 +++++ src/Encoder.gd | 122 +++++++++++++++++++++++++++++++++++++ src/Encoder.gd.uid | 1 + src/Martin1.gd | 50 +++++++++++++++ src/Martin1.gd.uid | 1 + src/RobotBW8.gd | 41 +++++++++++++ src/RobotBW8.gd.uid | 1 + tests/checker.png | Bin 0 -> 1145 bytes tests/checker.png.import | 34 +++++++++++ tests/spiral.png | Bin 0 -> 2304 bytes tests/spiral.png.import | 34 +++++++++++ tests/testtest.png | Bin 0 -> 6430 bytes tests/testtest.png.import | 34 +++++++++++ tests/testtest2.png | Bin 0 -> 2159 bytes tests/testtest2.png.import | 34 +++++++++++ tests/testtest3.png | Bin 0 -> 1458 bytes tests/testtest3.png.import | 34 +++++++++++ 22 files changed, 527 insertions(+) create mode 100644 icon.svg create mode 100644 icon.svg.import create mode 100644 node_3d.gd create mode 100644 node_3d.gd.uid create mode 100644 node_3d.tscn create mode 100644 project.godot create mode 100644 src/Encoder.gd create mode 100644 src/Encoder.gd.uid create mode 100644 src/Martin1.gd create mode 100644 src/Martin1.gd.uid create mode 100644 src/RobotBW8.gd create mode 100644 src/RobotBW8.gd.uid create mode 100644 tests/checker.png create mode 100644 tests/checker.png.import create mode 100644 tests/spiral.png create mode 100644 tests/spiral.png.import create mode 100644 tests/testtest.png create mode 100644 tests/testtest.png.import create mode 100644 tests/testtest2.png create mode 100644 tests/testtest2.png.import create mode 100644 tests/testtest3.png create mode 100644 tests/testtest3.png.import diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..9d8b7fa --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..3329385 --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ditahryq1qbup" +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/node_3d.gd b/node_3d.gd new file mode 100644 index 0000000..a478002 --- /dev/null +++ b/node_3d.gd @@ -0,0 +1,30 @@ +extends Node3D + +func encode_sstv(): + #var encoder = Martin1.new() + var encoder = RobotBW8.new() + var cameraImage = get_viewport().get_texture().get_image() + #var cameraImage = load("res://checker.png").get_image() + #var cameraImage = load("res://spiral.png").get_image() + #var cameraImage = load("res://testtest.png").get_image() + #var cameraImage = load("res://testtest2.png").get_image() + #var cameraImage = load("res://testtest3.png").get_image() + var audioBuffer = encoder.EncodeSSTV(cameraImage) + + # Spew that audio yo. + $AudioStreamPlayer.stream.mix_rate = SSTVEncoder.SAMPLE_RATE + $AudioStreamPlayer.stream.buffer_length = 120 + $AudioStreamPlayer.play() + var player = $AudioStreamPlayer.get_stream_playback() + for i in range(0, audioBuffer.size()): + player.push_frame(Vector2(audioBuffer[i], audioBuffer[i])) + +# a lil hacky delay so sdfgi can settle lol. +var startTimer = 0 +var first = true +func _process(delta): + if startTimer > 10 and first: + first = false + encode_sstv() + + startTimer += 1 diff --git a/node_3d.gd.uid b/node_3d.gd.uid new file mode 100644 index 0000000..6e7e83b --- /dev/null +++ b/node_3d.gd.uid @@ -0,0 +1 @@ +uid://bx4xg8k3m1wos diff --git a/node_3d.tscn b/node_3d.tscn new file mode 100644 index 0000000..8aabbae --- /dev/null +++ b/node_3d.tscn @@ -0,0 +1,56 @@ +[gd_scene load_steps=8 format=3 uid="uid://dt230shblncgx"] + +[ext_resource type="Script" uid="uid://bx4xg8k3m1wos" path="res://node_3d.gd" id="1_a202f"] + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_a202f"] + +[sub_resource type="Sky" id="Sky_noarx"] +sky_material = SubResource("ProceduralSkyMaterial_a202f") + +[sub_resource type="Environment" id="Environment_a0tk4"] +background_mode = 2 +sky = SubResource("Sky_noarx") +sdfgi_enabled = true + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_r3fl7"] +albedo_color = Color(1, 0, 0, 1) +emission_enabled = true +emission = Color(1, 0, 0, 1) +emission_energy_multiplier = 3.02 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_jka67"] +albedo_color = Color(0, 1, 0, 1) +emission_enabled = true +emission = Color(0, 1, 0, 1) +emission_energy_multiplier = 3.02 + +[sub_resource type="AudioStreamGenerator" id="AudioStreamGenerator_a202f"] + +[node name="Node3D" type="Node3D"] +script = ExtResource("1_a202f") + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_a0tk4") + +[node name="Camera3D" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.997971, 0) + +[node name="CSGBox3D" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.23108, -0.464242, -4.94434) +use_collision = true +size = Vector3(9.60767, 1, 10.8887) + +[node name="CSGBox3D2" type="CSGBox3D" parent="."] +transform = Transform3D(0.966061, 0, 0.258313, 0, 1, 0, -0.258313, 0, 0.966061, -0.617795, 0.535758, -2.20278) +material = SubResource("StandardMaterial3D_r3fl7") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(-0.886604, 0.302007, -0.350322, 0.226305, 0.943798, 0.240896, 0.403386, 0.1343, -0.905121, 0, 1.9072, 0) +shadow_enabled = true + +[node name="CSGBox3D3" type="CSGBox3D" parent="."] +transform = Transform3D(0.869943, 0, -0.493152, 0, 1, 0, 0.493152, 0, 0.869943, 1.11562, 0.535758, -2.43883) +material = SubResource("StandardMaterial3D_jka67") + +[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."] +stream = SubResource("AudioStreamGenerator_a202f") diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..241f5fa --- /dev/null +++ b/project.godot @@ -0,0 +1,16 @@ +; 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="SSTV" +run/main_scene="uid://dt230shblncgx" +config/features=PackedStringArray("4.4", "Forward Plus") +config/icon="res://icon.svg" diff --git a/src/Encoder.gd b/src/Encoder.gd new file mode 100644 index 0000000..93aebab --- /dev/null +++ b/src/Encoder.gd @@ -0,0 +1,122 @@ +extends Node +class_name SSTVEncoder + +const TWO_PI = PI * 2 +const SAMPLE_RATE = 48000.0 +const VIS_BIT_FREQ = { + 'ONE': 1100.0, + 'ZERO': 1300.0, +} +const PREFIX_PULSE_LENGTH = 0.1 # 100 ms +const HEADER_PULSE_LENGTH = 0.3 # 300 ms +const HEADER_BREAK_LENGTH = 0.01 # 10 ms +const VIS_BIT_LENGTH = 0.03 # 30 ms +const SYNC_PULSE_FREQ = 1200.0 + +var outputFloats = PackedFloat32Array() + +func EncodePrefix(): + outputFloats.append_array(GenerateTone(1900, PREFIX_PULSE_LENGTH)) + outputFloats.append_array(GenerateTone(1500, PREFIX_PULSE_LENGTH)) + outputFloats.append_array(GenerateTone(1900, PREFIX_PULSE_LENGTH)) + outputFloats.append_array(GenerateTone(1500, PREFIX_PULSE_LENGTH)) + outputFloats.append_array(GenerateTone(2300, PREFIX_PULSE_LENGTH)) + outputFloats.append_array(GenerateTone(1500, PREFIX_PULSE_LENGTH)) + outputFloats.append_array(GenerateTone(2300, PREFIX_PULSE_LENGTH)) + outputFloats.append_array(GenerateTone(1500, PREFIX_PULSE_LENGTH)) + +func EncodeHeader(vis: Array): + outputFloats.append_array(GenerateTone(1900, HEADER_PULSE_LENGTH)) + outputFloats.append_array(GenerateTone(SYNC_PULSE_FREQ, HEADER_BREAK_LENGTH)) + outputFloats.append_array(GenerateTone(1900, HEADER_PULSE_LENGTH)) + + # VIS Code + outputFloats.append_array(GenerateTone(SYNC_PULSE_FREQ, VIS_BIT_LENGTH)) + + var parity = 0 + vis.reverse() + for bit in vis: + var bit_freq = VIS_BIT_FREQ["ONE"] if bit else VIS_BIT_FREQ["ZERO"] + if bit: + parity += 1 + outputFloats.append_array(GenerateTone(bit_freq, VIS_BIT_LENGTH)) + + var parity_freq = VIS_BIT_FREQ["ZERO"] if parity % 2 == 0 else VIS_BIT_FREQ["ONE"] + outputFloats.append_array(GenerateTone(parity_freq, VIS_BIT_LENGTH)) + + outputFloats.append_array(GenerateTone(SYNC_PULSE_FREQ, VIS_BIT_LENGTH)) + +func GenerateTone(frequency: float, duration: float) -> PackedFloat32Array: + var samples = PackedFloat32Array() + var total_samples = int(duration * SAMPLE_RATE) + + for i in range(total_samples): + var time = float(i) / SAMPLE_RATE + var sample = sin(TWO_PI * frequency * time) + samples.append(sample) + + return samples + +func GenerateToneFromCurve(frequencies: Array, duration: float) -> PackedFloat32Array: + var samples = PackedFloat32Array() + var totalSamples = int(duration * SAMPLE_RATE) + var num_points = frequencies.size() + + var phase = 0.0 + var timeStep = 1.0 / SAMPLE_RATE + + for i in range(totalSamples): + var time = float(i) * timeStep + var normalized_time = time / duration + var index_f = normalized_time * (num_points - 1) + var index = int(index_f) + var frac = index_f - index + var freq: float + + if index >= num_points - 1: + freq = frequencies[num_points - 1] + else: + freq = lerp(frequencies[index], frequencies[index + 1], frac) + + phase += TWO_PI * freq * timeStep + + var sample = sin(phase) + samples.append(sample) + + return samples + +#func save_wav(path: String, samples: PackedFloat32Array) -> void: + #var file = FileAccess.open(path, FileAccess.WRITE) + #var byte_data = PackedByteArray() +# + #var num_samples = samples.size() + #var data_chunk_size = num_samples * 2 + #var file_size = 44 + data_chunk_size - 8 +# + ## WAV Header + #byte_data.append_array("RIFF".to_ascii_buffer()) + #byte_data.append_array(to_little_endian(file_size, 4)) + #byte_data.append_array("WAVEfmt ".to_ascii_buffer()) + #byte_data.append_array(to_little_endian(16, 4)) # PCM header size + #byte_data.append_array(to_little_endian(1, 2)) # PCM format + #byte_data.append_array(to_little_endian(1, 2)) + #byte_data.append_array(to_little_endian(SAMPLE_RATE, 4)) + #byte_data.append_array(to_little_endian(SAMPLE_RATE * 1 * 16 / 8, 4)) # Byte rate + #byte_data.append_array(to_little_endian(1 * 16 / 8, 2)) # Block align + #byte_data.append_array(to_little_endian(16, 2)) + #byte_data.append_array("data".to_ascii_buffer()) + #byte_data.append_array(to_little_endian(data_chunk_size, 4)) +# + ## Sample data + #for sample in samples: + #var int_sample = int(clamp(sample * 32767, -32767, 32767)) + #byte_data.append_array(to_little_endian(int_sample, 2)) +# + #file.store_buffer(byte_data) + #file.close() +# +#func to_little_endian(value: int, byte_count: int) -> PackedByteArray: + #var ba = PackedByteArray() + #for i in range(byte_count): + #ba.append((value >> (8 * i)) & 0xFF) + #return ba diff --git a/src/Encoder.gd.uid b/src/Encoder.gd.uid new file mode 100644 index 0000000..044a906 --- /dev/null +++ b/src/Encoder.gd.uid @@ -0,0 +1 @@ +uid://3qtsqt2dj0je diff --git a/src/Martin1.gd b/src/Martin1.gd new file mode 100644 index 0000000..75962d2 --- /dev/null +++ b/src/Martin1.gd @@ -0,0 +1,50 @@ +extends SSTVEncoder +class_name Martin1 + +const BLANKING_PULSE_FREQ = 1500.0 +const COLOR_FREQ_MULT = 3.1372549 + +func get_rgb_value_as_freq(image: Image, scan_line: int, vert_pos: int) -> Array: + #var index = scan_line * (vertResolution * 4) + vert_pos * 4 + var color = image.get_pixel(vert_pos, scan_line) + var red = float(color.r8) * COLOR_FREQ_MULT + 1500.0 + var green = float(color.g8) * COLOR_FREQ_MULT + 1500.0 + var blue = float(color.b8) * COLOR_FREQ_MULT + 1500.0 + return [red, green, blue] + +var numScanLines = 256.0 +var vertResolution = 320.0 +var blankingInterval = 0.000572 +var scanLineLength = 0.146432 +var syncPulseLength = 0.004862 +var preparedImage = [] + +func PrepareImage(image: Image): + image.resize(vertResolution, numScanLines) + image.convert(Image.FORMAT_RGB8) + + for scanLine in range(0, numScanLines): + var red = [] + var green = [] + var blue = [] + for vertPos in range(0, vertResolution): + var freqs = get_rgb_value_as_freq(image, scanLine, vertPos) + red.push_back(freqs[0]); + green.push_back(freqs[1]); + blue.push_back(freqs[2]); + preparedImage.push_back([green, blue, red]); + +func EncodeSSTV(image: Image): + PrepareImage(image) + + EncodePrefix() + EncodeHeader([false, true, false, true, true, false, false]) + + for scanLine in range(0, numScanLines): + outputFloats.append_array(GenerateTone(SYNC_PULSE_FREQ, syncPulseLength)) + outputFloats.append_array(GenerateTone(BLANKING_PULSE_FREQ, blankingInterval)) + for dataLine in range(0, 3): + outputFloats.append_array(GenerateToneFromCurve(preparedImage[scanLine][dataLine], scanLineLength)) + outputFloats.append_array(GenerateTone(BLANKING_PULSE_FREQ, blankingInterval)) + + return outputFloats diff --git a/src/Martin1.gd.uid b/src/Martin1.gd.uid new file mode 100644 index 0000000..b62f903 --- /dev/null +++ b/src/Martin1.gd.uid @@ -0,0 +1 @@ +uid://cprn0ne0v2x2u diff --git a/src/RobotBW8.gd b/src/RobotBW8.gd new file mode 100644 index 0000000..ee85bf1 --- /dev/null +++ b/src/RobotBW8.gd @@ -0,0 +1,41 @@ +extends SSTVEncoder +class_name RobotBW8 + +var preparedImage: Array + +const BLACK = 1500.0 +const WHITE = 2300.0 +const COLOR_FREQ_MULT = 3.1372549 +const BLANKING_PULSE_FREQ = 1500.0 + +const SYNC_PULSE = 1200.0 + +var scanLineLength = 0.056 +var syncPulseLength = 0.01 +var blankingInterval = 0.000572 +var numScanLines = 120 + +func PrepareImage(image: Image): + image.resize(160, numScanLines) + image.convert(Image.FORMAT_RGB8) + + for h in range(image.get_height()): + var line = PackedFloat32Array() + for w in range(image.get_width()): + var color = image.get_pixel(w, h) + line.push_back(round((color.r8 + color.g8 + color.b8) / 3) * COLOR_FREQ_MULT + BLACK) + preparedImage.push_back(line) + +func EncodeSSTV(image: Image): + PrepareImage(image) + + EncodePrefix() + EncodeHeader([false, false, false, false, false, true, false]) + + for scanLine in range(0, numScanLines): + outputFloats.append_array(GenerateTone(SYNC_PULSE_FREQ, syncPulseLength)) + outputFloats.append_array(GenerateTone(BLANKING_PULSE_FREQ, blankingInterval)) + outputFloats.append_array(GenerateToneFromCurve(preparedImage[scanLine], scanLineLength)) + outputFloats.append_array(GenerateTone(BLANKING_PULSE_FREQ, blankingInterval)) + + return outputFloats diff --git a/src/RobotBW8.gd.uid b/src/RobotBW8.gd.uid new file mode 100644 index 0000000..bb9dead --- /dev/null +++ b/src/RobotBW8.gd.uid @@ -0,0 +1 @@ +uid://bqk3kugv2vy3f diff --git a/tests/checker.png b/tests/checker.png new file mode 100644 index 0000000000000000000000000000000000000000..0a5593693b1c465b6fe27a4d49ef47c688eb01f9 GIT binary patch literal 1145 zcmeAS@N?(olHy`uVBq!ia0y~yU~~Xt1`al$$e|PKj{zyh;vjb?#+xT~>VX`VbVpxD z28NCO+atyOo|W~E(
ZprQphIp^UZbxA6;DWal(QWlJkG@CIbB z&23;Xb6C4|8za*VhOO6bv2i3YU!k5PufPGe7e*O0w&fcmlbOSGhwNNtmJN(qYqx@I zU9t6=nFE9Lf@@K?85lwSrH14N#$7Csz`2lmftm(maW5!-Xm86~W|o`=y+*1>JVts- zVBP|Z8rr5dsHNa|KfQofX&UA=c8(hiu}oA=ZFN5x`nG#`{?c}w0L<+Sp00i_>zopr E0A6gKGynhq literal 0 HcmV?d00001 diff --git a/tests/checker.png.import b/tests/checker.png.import new file mode 100644 index 0000000..99d5ccb --- /dev/null +++ b/tests/checker.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://doprjuugw7ga7" +path="res://.godot/imported/checker.png-6bb199bedbd039461e4248c1d0b9691d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://checker.png" +dest_files=["res://.godot/imported/checker.png-6bb199bedbd039461e4248c1d0b9691d.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/tests/spiral.png b/tests/spiral.png new file mode 100644 index 0000000000000000000000000000000000000000..1fd630168a6c6e2ba6593313aefe011a3f929a7d GIT binary patch literal 2304 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 literal 0 HcmV?d00001 diff --git a/tests/testtest.png.import b/tests/testtest.png.import new file mode 100644 index 0000000..ea2646d --- /dev/null +++ b/tests/testtest.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b44c511u6oile" +path="res://.godot/imported/testtest.png-3138b9f8c3bb6f85feeb295d99c6a7a2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://testtest.png" +dest_files=["res://.godot/imported/testtest.png-3138b9f8c3bb6f85feeb295d99c6a7a2.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/tests/testtest2.png b/tests/testtest2.png new file mode 100644 index 0000000000000000000000000000000000000000..9f571b25301333494fd9df714fa39dce1fe6d948 GIT binary patch literal 2159 zcmeAS@N?(olHy`uVBq!ia0y~yU~~Xt1`al$$e|PKj{zyp0*}aI1_skBAj}w-`jmr# zfrH)C#WAE}&f9ATIS&}{usCY}{k~?)gZNDb!Hoxg+_0?v_M!gqOs#KcuB#Wk{P~MP zZ>@i*;Vh-Y3}G4vcvx>FGH8n=v@yLgXb|NxaAqu%IKag^VgvdGp-3}kmTAhs(m!*Mw88GmKiNBMvKbPYGM#nk$vL1F)T7y;$5Zz i+X;NB5uRzjz6@GGHn52R2A6^-gJ@4zKbLh*2~7ZL4~vWd literal 0 HcmV?d00001 diff --git a/tests/testtest2.png.import b/tests/testtest2.png.import new file mode 100644 index 0000000..867e061 --- /dev/null +++ b/tests/testtest2.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://t5rtcbk8u7yo" +path="res://.godot/imported/testtest2.png-939c8d08bcfd841ad5a1a682e0766d88.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://testtest2.png" +dest_files=["res://.godot/imported/testtest2.png-939c8d08bcfd841ad5a1a682e0766d88.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/tests/testtest3.png b/tests/testtest3.png new file mode 100644 index 0000000000000000000000000000000000000000..18cc8be11615b3d5ea974c04744aa54aad0546f0 GIT binary patch literal 1458 zcmeAS@N?(olHy`uVBq!ia0y~yU~~Xt1`al$$e|PKj{zyp0*}aI1_skBAj}w-`jmr# zfz`{?#WAE}&f9Yvc@H=Uuq=GN|7E$P^`w&=JFCCHyH{P_Kl7*mKBuOcm5*J3!~-y) ztukY#xgU^V2NR>xqrozo9N0&*!N|@A{8Jg1hM4c!76B}3`BEc1(|mmyw18}2DGLUd Qf+vG$Pgg&ebxsLQ0FC*3k^lez literal 0 HcmV?d00001 diff --git a/tests/testtest3.png.import b/tests/testtest3.png.import new file mode 100644 index 0000000..ab96a3c --- /dev/null +++ b/tests/testtest3.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cqyo3c1lqmrf5" +path="res://.godot/imported/testtest3.png-6018875a4a62a4fd97780d49f559d924.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://testtest3.png" +dest_files=["res://.godot/imported/testtest3.png-6018875a4a62a4fd97780d49f559d924.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