summaryrefslogtreecommitdiffstats
path: root/Scripts
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-10-20 14:52:11 -0700
committeryum <yum.food.vr@gmail.com>2025-10-20 14:52:11 -0700
commit434fed1cd6092c7c8cc24bc2cbd95d1d4a425494 (patch)
treed001d8e4bdd8b4d04a007fe395722e3bb7038b1a /Scripts
parent630573cb0b4db15cbe155d674bf2c0f61d0f86b6 (diff)
continue work on decoder, support auto tile size
Diffstat (limited to 'Scripts')
-rw-r--r--Scripts/DataDecoder.asset10
-rw-r--r--Scripts/DataDecoder.cs67
2 files changed, 64 insertions, 13 deletions
diff --git a/Scripts/DataDecoder.asset b/Scripts/DataDecoder.asset
index ddfcdfe..26b5e70 100644
--- a/Scripts/DataDecoder.asset
+++ b/Scripts/DataDecoder.asset
@@ -104,13 +104,13 @@ MonoBehaviour:
Data:
- Name: $k
Entry: 1
- Data: tileSize
+ Data: tileToCheck
- Name: $v
Entry: 7
Data: 5|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
- Data: tileSize
+ Data: tileToCheck
- Name: <UserType>k__BackingField
Entry: 7
Data: 6|System.RuntimeType, mscorlib
@@ -158,13 +158,13 @@ MonoBehaviour:
Data:
- Name: $k
Entry: 1
- Data: tileToCheck
+ Data: tileSize
- Name: $v
Entry: 7
Data: 8|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
- Data: tileToCheck
+ Data: tileSize
- Name: <UserType>k__BackingField
Entry: 9
Data: 6
@@ -182,7 +182,7 @@ MonoBehaviour:
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
- Data: true
+ Data: false
- Name: _fieldAttributes
Entry: 7
Data: 9|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
diff --git a/Scripts/DataDecoder.cs b/Scripts/DataDecoder.cs
index 810c46a..1128e2f 100644
--- a/Scripts/DataDecoder.cs
+++ b/Scripts/DataDecoder.cs
@@ -1,3 +1,4 @@
+using System.Collections.Generic;
using UdonSharp;
using UnityEngine;
using VRC.SDK3.Rendering;
@@ -6,9 +7,12 @@ using VRC.Udon.Common.Interfaces;
public class DataDecoder : UdonSharpBehaviour
{
public RenderTexture sourceTexture;
- public int tileSize = 8;
public int tileToCheck = 0;
+ private int tileSize = 8;
+ // Minimum size (in pixels) of a tile. This is shared with our tixl operator.
+ private const int kMinTileSize = 4;
+ private const int kMaxTileSize = 128;
private Color32[] pixelData;
private bool hasData = false;
private int readWidth;
@@ -18,9 +22,8 @@ public class DataDecoder : UdonSharpBehaviour
void Update()
{
- if (sourceTexture == null || tileSize <= 0) return;
+ if (sourceTexture == null) return;
- // TODO get more than one column
int requestWidth = Mathf.Min(tileSize, sourceTexture.width);
int requestHeight = sourceTexture.height;
int pixelCount = requestWidth * requestHeight;
@@ -62,21 +65,69 @@ public class DataDecoder : UdonSharpBehaviour
private void ProcessTiles()
{
- if (pixelData == null || readWidth <= 0 || readHeight <= 0) return;
+ // Get the tile size.
+ {
+ int oldTileSize = tileSize;
+ tileSize = kMinTileSize;
+ tileSize = Parse24BitTile(0);
+ tileSize = Mathf.Clamp(tileSize, kMinTileSize, kMaxTileSize);
+ if (tileSize != oldTileSize) {
+ Debug.Log($"Tile size changed from {oldTileSize} to {tileSize}");
+ }
+ }
+
+ // Get the length. This is in units of subpixels. So we will need to access
+ // ceil(length/3) tiles.
+ int lengthSubpixels = Parse24BitTile(1);
+ int lengthTiles = (int) Mathf.Ceil(lengthSubpixels/3.0f);
+
+ // Collect all nibbles into a flat array. Note that these are still
+ // encoded.
+ var nibbles = new List<int>(lengthSubpixels);
+ for (int tile_i = 0; tile_i < lengthTiles; tile_i++) {
+ GetTileRGB(tile_i+2, out int r, out int g, out int b);
+ nibbles.Add(r);
+ if (nibbles.Count < nibbles.Capacity) {
+ nibbles.Add(g);
+ }
+ if (nibbles.Count < nibbles.Capacity) {
+ nibbles.Add(b);
+ }
+ }
+
+ // Convert nibbles to bytes.
+ var bytes = nibbles;
+ for (int i = 0; i < nibbles.Count/2; i++) {
+ // See DataEncoder.cs. It puts the upper 4 bits before the lower 4 bits.
+ bytes[i] = (nibbles[2*i] & 0xF0) | ((nibbles[2*i+1] & 0xF0) >> 4);
+ }
+ // Remove second half of list.
+ bytes.RemoveRange(nibbles.Count/2, nibbles.Count/2);
int tilesPerColumn = (int) Mathf.Floor(readHeight / tileSize);
+ }
+
+ private int Parse24BitTile(int tileIdx)
+ {
+ GetTileRGB(tileIdx, out int r, out int g, out int b);
+ int data = 0;
+ data |= DecodeNibble(r);
+ data |= DecodeNibble(g) << 4;
+ data |= DecodeNibble(b) << 8;
+ return data;
+ }
- GetTileRGB(tileToCheck, out int r, out int g, out int b);
- Debug.Log($"Tile {tileToCheck}: R={r}, G={g}, B={b}");
+ private int DecodeNibble(int subpixel) {
+ return (subpixel >> 4) & 0x0F;
}
- private void GetTileRGB(int tileIndex, out int r, out int g, out int b)
+ private void GetTileRGB(int tileIdx, out int r, out int g, out int b)
{
r = 0;
g = 0;
b = 0;
- int tileY = tileIndex * tileSize;
+ int tileY = tileIdx * tileSize;
int centerY = tileY + tileSize / 2;
if (centerY >= readHeight) return;