Skip to content

Commit 3ff54be

Browse files
committed
Add TubeRenderer to reflection list.
1 parent 32b2435 commit 3ff54be

File tree

3 files changed

+209
-1
lines changed

3 files changed

+209
-1
lines changed

Runtime/Code/Luau/ReflectionList.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ public static class ReflectionList {
208208
["ElRaccoone.Tweens.NativeTween+LocalPositionDriver"] = LuauContextAll,
209209
["ElRaccoone.Tweens.NativeTween+LocalRotationDriver"] = LuauContextAll,
210210
["ActiveAccessory[]"] = LuauContextAll,
211+
["TubeRendererCS"] = LuauContextAll,
211212
};
212213

213214
public static Dictionary<Type, LuauContext> allowedTypesInternal;
@@ -252,7 +253,7 @@ public static bool IsAllowed(Type t, LuauContext context) {
252253
}
253254

254255

255-
var allowed = allowedTypesInternal.TryGetValue(t, out var mask) && (mask & context) != 0;
256+
var allowed = allowedTypesInternal.TryGetValue(t, out var mask) && (mask & context) != 0;
256257
if (!allowed) {
257258
if (t != null && !string.IsNullOrEmpty(t.Namespace) && t.Namespace.Contains("ElRaccoone")) {
258259
return true;
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
using UnityEngine;
2+
using UnityEngine.Serialization;
3+
4+
namespace Assets.Code.Misc {
5+
[LuauAPI]
6+
public class TubeRendererCS : MonoBehaviour {
7+
[SerializeField] Vector3[] _positions;
8+
[SerializeField] int _sides;
9+
[SerializeField] float _radiusOne;
10+
[SerializeField] float _radiusTwo;
11+
[SerializeField] bool _useWorldSpace = true;
12+
[SerializeField] bool _useTwoRadii = false;
13+
14+
private Vector3[] _vertices;
15+
private Mesh _mesh;
16+
private MeshFilter _meshFilter;
17+
private MeshRenderer _meshRenderer;
18+
19+
public Material material {
20+
get { return _meshRenderer.material; }
21+
set { _meshRenderer.material = value; }
22+
}
23+
24+
void Awake() {
25+
_meshFilter = GetComponent<MeshFilter>();
26+
if (_meshFilter == null) {
27+
_meshFilter = gameObject.AddComponent<MeshFilter>();
28+
}
29+
30+
_meshRenderer = GetComponent<MeshRenderer>();
31+
if (_meshRenderer == null) {
32+
_meshRenderer = gameObject.AddComponent<MeshRenderer>();
33+
}
34+
35+
_mesh = new Mesh();
36+
_meshFilter.mesh = _mesh;
37+
}
38+
39+
private void OnEnable() {
40+
_meshRenderer.enabled = true;
41+
}
42+
43+
private void OnDisable() {
44+
_meshRenderer.enabled = false;
45+
}
46+
47+
void Update() {
48+
GenerateMesh();
49+
}
50+
51+
public void SetStartRadius(float radius) {
52+
_radiusOne = radius;
53+
}
54+
55+
public float GetStartRadius() {
56+
return _radiusOne;
57+
}
58+
59+
public void SetEndRadius(float radius) {
60+
_radiusTwo = radius;
61+
}
62+
63+
public float GetEndRadius() {
64+
return _radiusTwo;
65+
}
66+
67+
public void SetSides(int sides) {
68+
_sides = sides;
69+
}
70+
71+
72+
73+
public void SetPositions(Vector3[] positions) {
74+
_positions = positions;
75+
GenerateMesh();
76+
}
77+
78+
private void GenerateMesh() {
79+
if (_mesh == null || _positions == null || _positions.Length <= 1) {
80+
_mesh = new Mesh();
81+
return;
82+
}
83+
84+
var verticesLength = _sides * _positions.Length;
85+
if (_vertices == null || _vertices.Length != verticesLength) {
86+
_vertices = new Vector3[verticesLength];
87+
88+
var indices = GenerateIndices();
89+
var uvs = GenerateUVs();
90+
91+
if (verticesLength > _mesh.vertexCount) {
92+
_mesh.vertices = _vertices;
93+
_mesh.triangles = indices;
94+
_mesh.uv = uvs;
95+
}
96+
else {
97+
_mesh.triangles = indices;
98+
_mesh.vertices = _vertices;
99+
_mesh.uv = uvs;
100+
}
101+
}
102+
103+
var currentVertIndex = 0;
104+
105+
for (int i = 0; i < _positions.Length; i++) {
106+
var circle = CalculateCircle(i);
107+
foreach (var vertex in circle) {
108+
_vertices[currentVertIndex++] = _useWorldSpace ? transform.InverseTransformPoint(vertex) : vertex;
109+
}
110+
}
111+
112+
_mesh.vertices = _vertices;
113+
_mesh.RecalculateNormals();
114+
_mesh.RecalculateBounds();
115+
116+
_meshFilter.mesh = _mesh;
117+
}
118+
119+
private Vector2[] GenerateUVs() {
120+
var uvs = new Vector2[_positions.Length * _sides];
121+
122+
for (int segment = 0; segment < _positions.Length; segment++) {
123+
for (int side = 0; side < _sides; side++) {
124+
var vertIndex = (segment * _sides + side);
125+
var u = side / (_sides - 1f);
126+
var v = segment / (_positions.Length - 1f);
127+
128+
uvs[vertIndex] = new Vector2(u, v);
129+
}
130+
}
131+
132+
return uvs;
133+
}
134+
135+
private int[] GenerateIndices() {
136+
// Two triangles and 3 vertices
137+
var indices = new int[_positions.Length * _sides * 2 * 3];
138+
139+
var currentIndicesIndex = 0;
140+
for (int segment = 1; segment < _positions.Length; segment++) {
141+
for (int side = 0; side < _sides; side++) {
142+
var vertIndex = (segment * _sides + side);
143+
var prevVertIndex = vertIndex - _sides;
144+
145+
// Triangle one
146+
indices[currentIndicesIndex++] = prevVertIndex;
147+
indices[currentIndicesIndex++] =
148+
(side == _sides - 1) ? (vertIndex - (_sides - 1)) : (vertIndex + 1);
149+
indices[currentIndicesIndex++] = vertIndex;
150+
151+
152+
// Triangle two
153+
indices[currentIndicesIndex++] =
154+
(side == _sides - 1) ? (prevVertIndex - (_sides - 1)) : (prevVertIndex + 1);
155+
indices[currentIndicesIndex++] =
156+
(side == _sides - 1) ? (vertIndex - (_sides - 1)) : (vertIndex + 1);
157+
indices[currentIndicesIndex++] = prevVertIndex;
158+
}
159+
}
160+
161+
return indices;
162+
}
163+
164+
private Vector3[] CalculateCircle(int index) {
165+
var dirCount = 0;
166+
var forward = Vector3.zero;
167+
168+
// If not first index
169+
if (index > 0) {
170+
forward += (_positions[index] - _positions[index - 1]).normalized;
171+
dirCount++;
172+
}
173+
174+
// If not last index
175+
if (index < _positions.Length - 1) {
176+
forward += (_positions[index + 1] - _positions[index]).normalized;
177+
dirCount++;
178+
}
179+
180+
// Forward is the average of the connecting edges directions
181+
forward = (forward / dirCount).normalized;
182+
var side = Vector3.Cross(forward, forward + new Vector3(.123564f, .34675f, .756892f)).normalized;
183+
var up = Vector3.Cross(forward, side).normalized;
184+
185+
var circle = new Vector3[_sides];
186+
var angle = 0f;
187+
var angleStep = (2 * Mathf.PI) / _sides;
188+
189+
var t = index / (_positions.Length - 1f);
190+
var radius = _useTwoRadii ? Mathf.Lerp(_radiusOne, _radiusTwo, t) : _radiusOne;
191+
192+
for (int i = 0; i < _sides; i++) {
193+
var x = Mathf.Cos(angle);
194+
var y = Mathf.Sin(angle);
195+
196+
circle[i] = _positions[index] + side * x * radius + up * y * radius;
197+
198+
angle += angleStep;
199+
}
200+
201+
return circle;
202+
}
203+
}
204+
}

Runtime/Code/Misc/TubeRendererCS.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)