com.github.asus4.texture-source 0.3.5-rc1 → 0.3.6-rc4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.attestation.p7m CHANGED
Binary file
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2022 Koki Ibukuro
3
+ Copyright (c) 2026 Koki Ibukuro
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -12,5 +12,23 @@ namespace TextureSource
12
12
  public abstract void Start();
13
13
  public abstract void Stop();
14
14
  public abstract void Next();
15
+
16
+ /// <summary>
17
+ /// The transform matrix that is applied in the <see cref="TextureTransformer"/>.
18
+ /// Defaults to identity matrix.
19
+ /// </summary>
20
+ public virtual Matrix4x4 TransformMatrix => Matrix4x4.identity;
21
+
22
+ /// <summary>
23
+ /// The size after transform. Defaults to the texture size.
24
+ /// </summary>
25
+ public virtual Vector2Int TransformSize
26
+ {
27
+ get
28
+ {
29
+ Texture tex = Texture;
30
+ return tex == null ? Vector2Int.zero : new Vector2Int(tex.width, tex.height);
31
+ }
32
+ }
15
33
  }
16
34
  }
@@ -83,12 +83,21 @@ namespace TextureSource
83
83
  /// <param name="scale">A scale</param>
84
84
  /// <returns>The transformed texture</returns>
85
85
  public RenderTexture Transform(Texture input, Vector2 offset, float eulerRotation, Vector2 scale)
86
+ {
87
+ return Transform(input, BuildMatrix(offset, eulerRotation, scale));
88
+ }
89
+
90
+ /// <summary>
91
+ /// Build a destination-UV → source-UV sampling matrix from offset, rotation, and scale.
92
+ /// Same convention used by <see cref="Transform(Texture, Vector2, float, Vector2)"/>.
93
+ /// </summary>
94
+ public static Matrix4x4 BuildMatrix(Vector2 offset, float eulerRotation, Vector2 scale)
86
95
  {
87
96
  Matrix4x4 trs = Matrix4x4.TRS(
88
97
  new Vector3(-offset.x, -offset.y, 0),
89
98
  Quaternion.Euler(0, 0, -eulerRotation),
90
99
  new Vector3(1f / scale.x, 1f / scale.y, 1));
91
- return Transform(input, PopMatrix * trs * PushMatrix);
100
+ return PopMatrix * trs * PushMatrix;
92
101
  }
93
102
 
94
103
  /// <summary>
@@ -32,7 +32,7 @@ namespace TextureSource
32
32
  [Tooltip("Event called when the aspect ratio changed")]
33
33
  public AspectChangeEvent OnAspectChange = new AspectChangeEvent();
34
34
 
35
- private ITextureSource activeSource;
35
+ private BaseTextureSource activeSource;
36
36
  private float aspect = float.NegativeInfinity;
37
37
  private TextureTransformer transformer;
38
38
 
@@ -67,7 +67,11 @@ namespace TextureSource
67
67
 
68
68
  private void OnDisable()
69
69
  {
70
- activeSource?.Stop();
70
+ if (activeSource != null)
71
+ {
72
+ activeSource.Stop();
73
+ activeSource = null;
74
+ }
71
75
  transformer?.Dispose();
72
76
  transformer = null;
73
77
  }
@@ -79,9 +83,7 @@ namespace TextureSource
79
83
  return;
80
84
  }
81
85
 
82
- Texture tex = trimToScreenAspect
83
- ? TrimToScreen(Texture)
84
- : Texture;
86
+ Texture tex = Transform();
85
87
  OnTexture?.Invoke(tex);
86
88
 
87
89
  float aspect = (float)tex.width / tex.height;
@@ -99,33 +101,52 @@ namespace TextureSource
99
101
  activeSource?.Next();
100
102
  }
101
103
 
102
- private Texture TrimToScreen(Texture texture)
104
+ private Texture Transform()
103
105
  {
104
- float srcAspect = (float)texture.width / texture.height;
105
- float dstAspect = (float)Screen.width / Screen.height;
106
+ Texture originalTex = activeSource.Texture;
107
+ Matrix4x4 transformMatrix = activeSource.TransformMatrix;
108
+ Vector2Int transformSize = activeSource.TransformSize;
109
+
110
+ bool needTrim = false;
111
+ Vector2Int dstSize = transformSize;
112
+ Matrix4x4 matrix = transformMatrix;
106
113
 
107
- // Allow 1% mismatch
108
- if (Mathf.Abs(srcAspect - dstAspect) < 0.01f)
114
+ if (trimToScreenAspect)
109
115
  {
110
- return texture;
116
+ float srcAspect = (float)transformSize.x / transformSize.y;
117
+ float dstAspect = (float)Screen.width / Screen.height;
118
+ // Allow 1% mismatch
119
+ needTrim = Mathf.Abs(srcAspect - dstAspect) >= 0.01f;
120
+ if (needTrim)
121
+ {
122
+ Utils.GetTargetSizeScale(transformSize, dstAspect, out dstSize, out Vector2 scale);
123
+ var trimMatrix = TextureTransformer.BuildMatrix(Vector2.zero, 0, scale);
124
+ matrix = transformMatrix * trimMatrix;
125
+ }
111
126
  }
112
127
 
113
- Utils.GetTargetSizeScale(
114
- new Vector2Int(texture.width, texture.height), dstAspect,
115
- out Vector2Int dstSize, out Vector2 scale);
116
-
117
- bool needInitialize = transformer == null || dstSize.x != transformer.width || dstSize.y != transformer.height;
118
- if (needInitialize)
128
+ if (!needTrim && transformMatrix.isIdentity)
119
129
  {
120
- transformer?.Dispose();
121
- // Copy the format if the source is a RenderTexture
122
- RenderTextureFormat format = (texture is RenderTexture renderTex)
123
- ? renderTex.format :
124
- RenderTextureFormat.ARGB32;
125
- transformer = new TextureTransformer(dstSize.x, dstSize.y, format);
130
+ return originalTex;
126
131
  }
127
132
 
128
- return transformer.Transform(texture, Vector2.zero, 0, scale);
133
+ EnsureTransformer(dstSize, originalTex);
134
+ return transformer.Transform(originalTex, matrix);
135
+ }
136
+
137
+ private void EnsureTransformer(Vector2Int size, Texture tex)
138
+ {
139
+ if (transformer != null && transformer.width == size.x && transformer.height == size.y)
140
+ {
141
+ // No need to recreate
142
+ return;
143
+ }
144
+ // Recreate transformer with new size
145
+ transformer?.Dispose();
146
+ RenderTextureFormat format = (tex is RenderTexture renderTex)
147
+ ? renderTex.format
148
+ : RenderTextureFormat.ARGB32;
149
+ transformer = new TextureTransformer(size.x, size.y, format);
129
150
  }
130
151
  }
131
152
  }
@@ -50,14 +50,33 @@ namespace TextureSource
50
50
  }
51
51
  }
52
52
 
53
- public override Texture Texture => NormalizeWebCam();
53
+ public override Texture Texture => webCamTexture;
54
+
55
+ public override Matrix4x4 TransformMatrix
56
+ {
57
+ get
58
+ {
59
+ EnsureNormalizeCacheFresh();
60
+ return transformMatrix;
61
+ }
62
+ }
63
+
64
+ public override Vector2Int TransformSize
65
+ {
66
+ get
67
+ {
68
+ EnsureNormalizeCacheFresh();
69
+ return transformSize;
70
+ }
71
+ }
54
72
 
55
73
  private WebCamDevice[] devices;
56
74
  private WebCamTexture webCamTexture;
57
75
  private int currentIndex;
58
- private TextureTransformer transformer;
59
76
  private int lastUpdatedFrame = -1;
60
77
  private bool isFrontFacing;
78
+ private Matrix4x4 transformMatrix = Matrix4x4.identity;
79
+ private Vector2Int transformSize;
61
80
 
62
81
  public CameraFacing[] FacingPriorities
63
82
  {
@@ -125,8 +144,7 @@ namespace TextureSource
125
144
  webCamTexture.Stop();
126
145
  webCamTexture = null;
127
146
  }
128
- transformer?.Dispose();
129
- transformer = null;
147
+ lastUpdatedFrame = -1;
130
148
  }
131
149
 
132
150
  public override void Next()
@@ -135,16 +153,17 @@ namespace TextureSource
135
153
  StartCamera(currentIndex);
136
154
  }
137
155
 
138
- private RenderTexture NormalizeWebCam()
156
+ private void EnsureNormalizeCacheFresh()
139
157
  {
140
158
  if (webCamTexture == null)
141
159
  {
142
- return null;
160
+ transformSize = Vector2Int.zero;
161
+ transformMatrix = Matrix4x4.identity;
162
+ return;
143
163
  }
144
-
145
164
  if (lastUpdatedFrame == Time.frameCount)
146
165
  {
147
- return transformer.Texture;
166
+ return;
148
167
  }
149
168
 
150
169
  bool isPortrait = webCamTexture.videoRotationAngle == 90 || webCamTexture.videoRotationAngle == 270;
@@ -154,13 +173,7 @@ namespace TextureSource
154
173
  {
155
174
  (width, height) = (height, width); // swap
156
175
  }
157
-
158
- bool needInitialize = transformer == null || width != transformer.width || height != transformer.height;
159
- if (needInitialize)
160
- {
161
- transformer?.Dispose();
162
- transformer = new TextureTransformer(width, height, RenderTextureFormat.ARGB32);
163
- }
176
+ transformSize = new Vector2Int(width, height);
164
177
 
165
178
  Vector2 scale;
166
179
  if (isPortrait)
@@ -171,12 +184,9 @@ namespace TextureSource
171
184
  {
172
185
  scale = new Vector2(isFrontFacing ? -1 : 1, webCamTexture.videoVerticallyMirrored ? -1 : 1);
173
186
  }
174
- transformer.Transform(webCamTexture, Vector2.zero, -webCamTexture.videoRotationAngle, scale);
175
-
176
- // Debug.Log($"mirrored: {webCamTexture.videoVerticallyMirrored}, angle: {webCamTexture.videoRotationAngle}, isFrontFacing: {isFrontFacing}");
187
+ transformMatrix = TextureTransformer.BuildMatrix(Vector2.zero, -webCamTexture.videoRotationAngle, scale);
177
188
 
178
189
  lastUpdatedFrame = Time.frameCount;
179
- return transformer.Texture;
180
190
  }
181
191
  }
182
192
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.github.asus4.texture-source",
3
- "version": "0.3.5-rc1",
3
+ "version": "0.3.6-rc4",
4
4
  "displayName": "TextureSource",
5
5
  "description": "Simplify WebCamera and test video handling for using Computer Vision in Unity",
6
6
  "unity": "2020.3",
@@ -11,6 +11,11 @@
11
11
  ],
12
12
  "documentationUrl": "https://github.com/asus4/TextureSource/tree/main",
13
13
  "changelogUrl": "https://github.com/asus4/TextureSource/releases",
14
+ "repository": {
15
+ "url": "https://github.com/asus4/TextureSource",
16
+ "type": "git",
17
+ "revision": "16b280c6c160c50c1f0d9a1458514de9c4b3c0be"
18
+ },
14
19
  "license": "MIT",
15
20
  "licensesUrl": "https://github.com/asus4/TextureSource/blob/main/Packages/com.github.asus4.texture-source/LICENSE",
16
21
  "author": {
@@ -19,10 +24,5 @@
19
24
  },
20
25
  "dependencies": {
21
26
  "com.unity.modules.video": "1.0.0"
22
- },
23
- "repository": {
24
- "url": "git@github.com:asus4/TextureSource.git",
25
- "type": "git",
26
- "revision": "46a8a731a48076003bcc6e9182a33f905da31922"
27
27
  }
28
28
  }