Skip to content

Commit c886436

Browse files
Add files via upload
1 parent faf9e9d commit c886436

File tree

90 files changed

+18066
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+18066
-0
lines changed

C_BaseViewModel.cs

Lines changed: 808 additions & 0 deletions
Large diffs are not rendered by default.

C_BaseViewModel.cs.meta

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

Decal.meta

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

Decal/Decal.cs

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
#if UNITY_EDITOR
5+
using UnityEditor;
6+
#endif
7+
using UnityEngine;
8+
using UnityEngine.Serialization;
9+
10+
namespace uSource.Decals
11+
{
12+
[RequireComponent(typeof(MeshFilter))]
13+
[RequireComponent(typeof(MeshRenderer))]
14+
[ExecuteInEditMode]
15+
public class Decal_ : MonoBehaviour
16+
{
17+
18+
[FormerlySerializedAs("material")] public Material Material;
19+
[FormerlySerializedAs("sprite")] public Sprite Sprite;
20+
21+
[FormerlySerializedAs("affectedLayers"), FormerlySerializedAs("AffectedLayers")] public LayerMask LayerMask = -1;
22+
[FormerlySerializedAs("maxAngle")] public float MaxAngle = 90.0f;
23+
[FormerlySerializedAs("pushDistance"), FormerlySerializedAs("PushDistance")] public float Offset = 0.009f;
24+
25+
public MeshFilter MeshFilter
26+
{
27+
get
28+
{
29+
return gameObject.GetComponent<MeshFilter>() ?? gameObject.AddComponent<MeshFilter>();
30+
}
31+
}
32+
public MeshRenderer MeshRenderer
33+
{
34+
get
35+
{
36+
return gameObject.GetComponent<MeshRenderer>() ?? gameObject.AddComponent<MeshRenderer>();
37+
}
38+
}
39+
40+
#if UNITY_EDITOR
41+
[MenuItem("GameObject/Decal")]
42+
internal static void Create()
43+
{
44+
new GameObject("Decal", typeof(Decal_), typeof(MeshFilter), typeof(MeshRenderer)).isStatic = true;
45+
}
46+
#endif
47+
48+
public void SetDirection()
49+
{
50+
float dist = (16 * uLoader.UnitScale) + 0.01f;
51+
List<Vector3> hits = new List<Vector3>();
52+
53+
if (Physics.Raycast(transform.position - new Vector3(0, 0, 0.01f), Vector3.forward, dist))
54+
hits.Add(Vector3.forward);
55+
56+
if (Physics.Raycast(transform.position - new Vector3(0, 0, -0.01f), Vector3.back, dist))
57+
hits.Add(Vector3.back);
58+
59+
if (Physics.Raycast(transform.position - new Vector3(0, 0.01f, 0), Vector3.up, dist))
60+
hits.Add(Vector3.up);
61+
62+
if (Physics.Raycast(transform.position - new Vector3(0, -0.01f, 0), Vector3.down, dist))
63+
hits.Add(Vector3.down);
64+
65+
if (Physics.Raycast(transform.position - new Vector3(0.01f, 0, 0), Vector3.right, dist))
66+
hits.Add(Vector3.right);
67+
68+
if (Physics.Raycast(transform.position - new Vector3(-0.01f, 0, 0), Vector3.left, dist))
69+
hits.Add(Vector3.left);
70+
71+
//Find median point
72+
if (hits.Count > 0)
73+
{
74+
Vector3 minPoint = hits[0];
75+
Vector3 maxPoint = hits[0];
76+
77+
for (int i = 1; i < hits.Count; i++)
78+
{
79+
Vector3 pos = hits[i];
80+
if (pos.x < minPoint.x)
81+
minPoint.x = pos.x;
82+
if (pos.x > maxPoint.x)
83+
maxPoint.x = pos.x;
84+
if (pos.y < minPoint.y)
85+
minPoint.y = pos.y;
86+
if (pos.y > maxPoint.y)
87+
maxPoint.y = pos.y;
88+
if (pos.z < minPoint.z)
89+
minPoint.z = pos.z;
90+
if (pos.z > maxPoint.z)
91+
maxPoint.z = pos.z;
92+
}
93+
94+
transform.forward = minPoint + 0.5f * (maxPoint - minPoint);
95+
}
96+
97+
float yDefault = 180;
98+
if (transform.eulerAngles.x < 0)
99+
yDefault = -270;
100+
if (transform.eulerAngles.x > 0)
101+
yDefault = 270;
102+
103+
transform.rotation *= Quaternion.Euler(0, 0, yDefault);
104+
}
105+
106+
public void OnValidate()
107+
{
108+
if (!Material) Sprite = null;
109+
if (Sprite && Material.mainTexture != Sprite.texture) Sprite = null;
110+
111+
MaxAngle = Mathf.Clamp(MaxAngle, 1, 180);
112+
Offset = Mathf.Clamp(Offset, 0.005f, 0.05f);
113+
}
114+
115+
void Awake()
116+
{
117+
var mesh = MeshFilter.sharedMesh;
118+
var meshes = GameObject.FindObjectsByType<Decal_>(FindObjectsSortMode.None).Select(i => i.MeshFilter.sharedMesh);
119+
if (meshes.Contains(mesh)) MeshFilter.sharedMesh = null; // if mesh was copied
120+
}
121+
122+
void OnEnable()
123+
{
124+
//if (Application.isPlaying)
125+
// enabled = false;
126+
}
127+
128+
void Update()
129+
{
130+
if (transform.hasChanged)
131+
{
132+
transform.hasChanged = false;
133+
BuildAndSetDirty();
134+
}
135+
}
136+
137+
void OnDrawGizmosSelected()
138+
{
139+
Gizmos.matrix = transform.localToWorldMatrix;
140+
Gizmos.color = Color.green;
141+
Gizmos.DrawWireCube(Vector3.zero, Vector3.one);
142+
143+
var bounds = DecalUtils.GetBounds(this);
144+
Gizmos.matrix = Matrix4x4.identity;
145+
Gizmos.color = Color.white;
146+
Gizmos.DrawWireCube(bounds.center, bounds.size + Vector3.one * 0.01f);
147+
}
148+
149+
150+
public void BuildAndSetDirty()
151+
{
152+
DecalBuilder.Build(this);
153+
DecalUtils.SetDirty(this);
154+
}
155+
}
156+
}

Decal/Decal.cs.meta

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

Decal/DecalEditor.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#if UNITY_EDITOR
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using UnityEditor;
5+
using UnityEngine;
6+
7+
namespace uSource.Decals
8+
{
9+
[CustomEditor(typeof(Decal_))]
10+
public class DecalEditor : Editor
11+
{
12+
private Decal_ Target
13+
{
14+
get { return (Decal_)target; }
15+
}
16+
17+
public override void OnInspectorGUI()
18+
{
19+
Target.Material = (Material)EditorGUILayout.ObjectField(Target.Material, typeof(Material), true);
20+
21+
if (Target.Material && Target.Material.mainTexture)
22+
{
23+
Target.Sprite = (Sprite)EditorGUILayout.ObjectField(Target.Sprite, typeof(Sprite), true);
24+
}
25+
26+
27+
EditorGUILayout.Separator();
28+
Target.LayerMask = GUIUtils.LayerMaskField("Layer Mask", Target.LayerMask);
29+
Target.MaxAngle = EditorGUILayout.Slider("Max Angle", Target.MaxAngle, 0, 180);
30+
Target.Offset = EditorGUILayout.Slider("Offset", Target.Offset, 0.001f, 0.05f);
31+
32+
EditorGUILayout.Separator();
33+
if (GUILayout.Button("Build"))
34+
Target.BuildAndSetDirty();
35+
36+
if (GUI.changed)
37+
{
38+
Target.OnValidate();
39+
Target.BuildAndSetDirty();
40+
GUI.changed = false;
41+
}
42+
}
43+
}
44+
}
45+
#endif

Decal/DecalEditor.cs.meta

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

Decal/Helpers.meta

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

Decal/Helpers/DecalBuilder.cs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using UnityEngine;
5+
6+
namespace uSource.Decals
7+
{
8+
static class DecalBuilder
9+
{
10+
private static readonly MeshBuilder Builder = new MeshBuilder();
11+
12+
public static void Build(Decal_ decal)
13+
{
14+
Build(Builder, decal);
15+
}
16+
17+
private static void Build(MeshBuilder builder, Decal_ decal)
18+
{
19+
var filter = decal.MeshFilter;
20+
var renderer = decal.MeshRenderer;
21+
22+
if (decal.Material && decal.Sprite)
23+
{
24+
builder.Clear();
25+
Build_(builder, decal);
26+
filter.sharedMesh = builder.ToMesh(filter.sharedMesh, GetUVRect(decal.Sprite), decal.Offset);
27+
renderer.sharedMaterial = decal.Material;
28+
}
29+
else
30+
{
31+
Object.DestroyImmediate(filter.sharedMesh);
32+
filter.sharedMesh = null;
33+
renderer.sharedMaterial = null;
34+
}
35+
}
36+
37+
private static void Build_(MeshBuilder builder, Decal_ decal)
38+
{
39+
var objects = DecalUtils.GetAffectedObjects(decal);
40+
var terrains = DecalUtils.GetAffectedTerrains(decal);
41+
var bounds = DecalUtils.GetBounds(decal);
42+
var worldToDecalMatrix = decal.transform.worldToLocalMatrix;
43+
44+
var triangles1 = MeshUtils.GetTriangles(objects, worldToDecalMatrix).Where(i => Filter(i, decal));
45+
var triangles2 = TerrainUtils.GetTriangles(terrains, bounds, worldToDecalMatrix).Where(i => Filter(i, decal));
46+
47+
AddTriangles(builder, triangles1);
48+
AddTriangles(builder, triangles2);
49+
}
50+
51+
// Add
52+
private static void AddTriangles(MeshBuilder builder, IEnumerable<Triangle> triangles)
53+
{
54+
foreach (var triangle in triangles)
55+
{
56+
AddTriangle(builder, triangle);
57+
}
58+
}
59+
60+
private static void AddTriangle(MeshBuilder builder, Triangle triangle)
61+
{
62+
var poly = PolygonUtils.Clip(triangle.V1, triangle.V2, triangle.V3);
63+
if (poly.Length > 0) builder.AddPolygon(poly);
64+
}
65+
66+
// Helpers
67+
private static bool Filter(Triangle triangle, Decal_ decal)
68+
{
69+
var normal = GetNormal(triangle);
70+
return Vector3.Angle(Vector3.back, normal) <= decal.MaxAngle;
71+
}
72+
73+
private static Vector3 GetNormal(Triangle triangle)
74+
{
75+
return Vector3.Cross(triangle.V2 - triangle.V1, triangle.V3 - triangle.V1).normalized;
76+
}
77+
78+
private static Rect GetUVRect(Sprite sprite)
79+
{
80+
return ToRect01(sprite.rect, sprite.texture);
81+
}
82+
83+
private static Rect ToRect01(Rect rect, Texture2D texture)
84+
{
85+
//rect.x /= texture.width;
86+
//rect.y /= texture.height;
87+
rect.width /= texture.width;
88+
rect.height /= texture.height;
89+
return rect;
90+
}
91+
}
92+
}

Decal/Helpers/DecalBuilder.cs.meta

Lines changed: 11 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)