1
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace Pinwheel.Jupiter
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class JAnimatableAttribute : Attribute
|
||||
{
|
||||
public string DisplayName { get; set; }
|
||||
public JCurveOrGradient CurveOrGradient { get; set; }
|
||||
|
||||
public JAnimatableAttribute(string displayName, JCurveOrGradient curveOrGradient)
|
||||
{
|
||||
DisplayName = displayName;
|
||||
CurveOrGradient = curveOrGradient;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,115 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pinwheel.Jupiter
|
||||
{
|
||||
[System.Serializable]
|
||||
public class JAnimatedProperty
|
||||
{
|
||||
[SerializeField]
|
||||
private string name;
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
name = string.Empty;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
set
|
||||
{
|
||||
name = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private string displayName;
|
||||
public string DisplayName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (displayName == null)
|
||||
{
|
||||
displayName = string.Empty;
|
||||
}
|
||||
return displayName;
|
||||
}
|
||||
set
|
||||
{
|
||||
displayName = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private JCurveOrGradient curveOrGradient;
|
||||
public JCurveOrGradient CurveOrGradient
|
||||
{
|
||||
get
|
||||
{
|
||||
return curveOrGradient;
|
||||
}
|
||||
set
|
||||
{
|
||||
curveOrGradient = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private AnimationCurve curve;
|
||||
public AnimationCurve Curve
|
||||
{
|
||||
get
|
||||
{
|
||||
if (curve == null)
|
||||
{
|
||||
curve = AnimationCurve.EaseInOut(0, 0, 1, 0);
|
||||
}
|
||||
return curve;
|
||||
}
|
||||
set
|
||||
{
|
||||
curve = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private Gradient gradient;
|
||||
public Gradient Gradient
|
||||
{
|
||||
get
|
||||
{
|
||||
if (gradient == null)
|
||||
{
|
||||
gradient = JUtilities.CreateFullWhiteGradient();
|
||||
}
|
||||
return gradient;
|
||||
}
|
||||
set
|
||||
{
|
||||
gradient = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float EvaluateFloat(float t)
|
||||
{
|
||||
return Curve.Evaluate(t);
|
||||
}
|
||||
|
||||
public Color EvaluateColor(float t)
|
||||
{
|
||||
return Gradient.Evaluate(t);
|
||||
}
|
||||
|
||||
public static JAnimatedProperty Create(string name, string displayName, JCurveOrGradient curveOrGradient)
|
||||
{
|
||||
JAnimatedProperty props = new JAnimatedProperty();
|
||||
props.name = name;
|
||||
props.displayName = displayName;
|
||||
props.curveOrGradient = curveOrGradient;
|
||||
return props;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pinwheel.Jupiter
|
||||
{
|
||||
public enum JCurveOrGradient
|
||||
{
|
||||
Curve, Gradient
|
||||
}
|
||||
}
|
@@ -0,0 +1,372 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Rendering;
|
||||
using System;
|
||||
|
||||
namespace Pinwheel.Jupiter
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
public class JDayNightCycle : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private JDayNightCycleProfile profile;
|
||||
public JDayNightCycleProfile Profile
|
||||
{
|
||||
get
|
||||
{
|
||||
return profile;
|
||||
}
|
||||
set
|
||||
{
|
||||
profile = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private JSky sky;
|
||||
public JSky Sky
|
||||
{
|
||||
get
|
||||
{
|
||||
return sky;
|
||||
}
|
||||
set
|
||||
{
|
||||
sky = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private bool useSunPivot;
|
||||
public bool UseSunPivot
|
||||
{
|
||||
get
|
||||
{
|
||||
return useSunPivot;
|
||||
}
|
||||
set
|
||||
{
|
||||
useSunPivot = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private Transform sunOrbitPivot;
|
||||
public Transform SunOrbitPivot
|
||||
{
|
||||
get
|
||||
{
|
||||
return sunOrbitPivot;
|
||||
}
|
||||
set
|
||||
{
|
||||
sunOrbitPivot = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private bool useMoonPivot;
|
||||
public bool UseMoonPivot
|
||||
{
|
||||
get
|
||||
{
|
||||
return useMoonPivot;
|
||||
}
|
||||
set
|
||||
{
|
||||
useMoonPivot = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private Transform moonOrbitPivot;
|
||||
public Transform MoonOrbitPivot
|
||||
{
|
||||
get
|
||||
{
|
||||
return moonOrbitPivot;
|
||||
}
|
||||
set
|
||||
{
|
||||
moonOrbitPivot = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private float startTime;
|
||||
public float StartTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return startTime;
|
||||
}
|
||||
set
|
||||
{
|
||||
startTime = Mathf.Clamp(value, 0f, 24f);
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private float timeIncrement;
|
||||
public float TimeIncrement
|
||||
{
|
||||
get
|
||||
{
|
||||
return timeIncrement;
|
||||
}
|
||||
set
|
||||
{
|
||||
timeIncrement = Mathf.Max(0, value);
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private bool autoTimeIncrement;
|
||||
public bool AutoTimeIncrement
|
||||
{
|
||||
get
|
||||
{
|
||||
return autoTimeIncrement;
|
||||
}
|
||||
set
|
||||
{
|
||||
autoTimeIncrement = value;
|
||||
}
|
||||
}
|
||||
|
||||
private float time;
|
||||
public float Time
|
||||
{
|
||||
get
|
||||
{
|
||||
return time % 24f;
|
||||
}
|
||||
set
|
||||
{
|
||||
time = value % 24f;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private bool shouldUpdateEnvironmentReflection;
|
||||
public bool ShouldUpdateEnvironmentReflection
|
||||
{
|
||||
get
|
||||
{
|
||||
return shouldUpdateEnvironmentReflection;
|
||||
}
|
||||
set
|
||||
{
|
||||
shouldUpdateEnvironmentReflection = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private int environmentReflectionResolution;
|
||||
public int EnvironmentReflectionResolution
|
||||
{
|
||||
get
|
||||
{
|
||||
return environmentReflectionResolution;
|
||||
}
|
||||
set
|
||||
{
|
||||
int oldValue = environmentReflectionResolution;
|
||||
int newValue = Mathf.Clamp(value, 16, 2048);
|
||||
environmentReflectionResolution = newValue;
|
||||
if (oldValue != newValue)
|
||||
{
|
||||
if (environmentReflection != null)
|
||||
{
|
||||
JUtilities.DestroyObject(environmentReflection);
|
||||
}
|
||||
if (environmentProbe != null)
|
||||
{
|
||||
JUtilities.DestroyGameobject(environmentProbe.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private ReflectionProbeTimeSlicingMode environmentReflectionTimeSlicingMode;
|
||||
public ReflectionProbeTimeSlicingMode EnvironmentReflectionTimeSlicingMode
|
||||
{
|
||||
get
|
||||
{
|
||||
return environmentReflectionTimeSlicingMode;
|
||||
}
|
||||
set
|
||||
{
|
||||
environmentReflectionTimeSlicingMode = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private ReflectionProbe environmentProbe;
|
||||
private ReflectionProbe EnvironmentProbe
|
||||
{
|
||||
get
|
||||
{
|
||||
if (environmentProbe == null)
|
||||
{
|
||||
GameObject probeGO = new GameObject("~EnvironmentReflectionRenderer");
|
||||
probeGO.transform.parent = transform;
|
||||
probeGO.transform.position = new Vector3(0, -1000, 0);
|
||||
probeGO.transform.rotation = Quaternion.identity;
|
||||
probeGO.transform.localScale = Vector3.one;
|
||||
probeGO.hideFlags = HideFlags.DontSave;
|
||||
|
||||
environmentProbe = probeGO.AddComponent<ReflectionProbe>();
|
||||
environmentProbe.resolution = EnvironmentReflectionResolution;
|
||||
environmentProbe.size = new Vector3(1, 1, 1);
|
||||
environmentProbe.cullingMask = 0;
|
||||
}
|
||||
environmentProbe.clearFlags = ReflectionProbeClearFlags.Skybox;
|
||||
environmentProbe.mode = ReflectionProbeMode.Realtime;
|
||||
environmentProbe.refreshMode = ReflectionProbeRefreshMode.ViaScripting;
|
||||
environmentProbe.timeSlicingMode = EnvironmentReflectionTimeSlicingMode;
|
||||
environmentProbe.hdr = false;
|
||||
|
||||
return environmentProbe;
|
||||
}
|
||||
}
|
||||
|
||||
private Cubemap environmentReflection;
|
||||
private Cubemap EnvironmentReflection
|
||||
{
|
||||
get
|
||||
{
|
||||
if (environmentReflection == null)
|
||||
{
|
||||
environmentReflection = new Cubemap(EnvironmentProbe.resolution, TextureFormat.RGBA32, true);
|
||||
}
|
||||
return environmentReflection;
|
||||
}
|
||||
}
|
||||
|
||||
private int probeRenderId = -1;
|
||||
|
||||
private float DeltaTime
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
return UnityEngine.Time.deltaTime;
|
||||
else
|
||||
return 1.0f / 60f;
|
||||
}
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
Sky = GetComponent<JSky>();
|
||||
StartTime = 0;
|
||||
TimeIncrement = 1;
|
||||
AutoTimeIncrement = true;
|
||||
Time = 0;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
time = StartTime;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
CleanUp();
|
||||
}
|
||||
private void CleanUp()
|
||||
{
|
||||
if (environmentProbe != null)
|
||||
{
|
||||
JUtilities.DestroyGameobject(environmentProbe.gameObject);
|
||||
}
|
||||
if (environmentReflection != null)
|
||||
{
|
||||
JUtilities.DestroyObject(environmentReflection);
|
||||
}
|
||||
if (Sky != null)
|
||||
{
|
||||
Sky.DNC = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
AnimateSky();
|
||||
if (ShouldUpdateEnvironmentReflection)
|
||||
{
|
||||
UpdateEnvironmentReflection();
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderSettings.defaultReflectionMode = DefaultReflectionMode.Skybox;
|
||||
}
|
||||
}
|
||||
|
||||
private void AnimateSky()
|
||||
{
|
||||
if (Profile == null)
|
||||
return;
|
||||
if (Sky == null)
|
||||
return;
|
||||
if (Sky.Profile == null)
|
||||
return;
|
||||
Sky.DNC = this;
|
||||
if (AutoTimeIncrement)
|
||||
{
|
||||
Time += TimeIncrement * DeltaTime;
|
||||
}
|
||||
float evalTime = Mathf.InverseLerp(0f, 24f, Time);
|
||||
Profile.Animate(Sky, evalTime);
|
||||
|
||||
if (Sky.Profile.EnableSun && Sky.SunLightSource != null)
|
||||
{
|
||||
float angle = evalTime * 360f;
|
||||
Matrix4x4 localRotationMatrix = Matrix4x4.Rotate(Quaternion.Euler(angle, 0, 0));
|
||||
Vector3 localDirection = localRotationMatrix.MultiplyVector(Vector3.up);
|
||||
|
||||
Transform pivot = (UseSunPivot && SunOrbitPivot != null) ? SunOrbitPivot : transform;
|
||||
Matrix4x4 localToWorld = pivot.localToWorldMatrix;
|
||||
Vector3 worldDirection = localToWorld.MultiplyVector(localDirection);
|
||||
Sky.SunLightSource.transform.forward = worldDirection;
|
||||
Sky.SunLightSource.color = Sky.Profile.Material.GetColor(JMat.SUN_LIGHT_COLOR);
|
||||
Sky.SunLightSource.intensity = Sky.Profile.Material.GetFloat(JMat.SUN_LIGHT_INTENSITY);
|
||||
}
|
||||
|
||||
if (Sky.Profile.EnableMoon && Sky.MoonLightSource != null)
|
||||
{
|
||||
float angle = evalTime * 360f;
|
||||
Matrix4x4 localRotationMatrix = Matrix4x4.Rotate(Quaternion.Euler(angle, 0, 0));
|
||||
Vector3 localDirection = localRotationMatrix.MultiplyVector(Vector3.down);
|
||||
|
||||
Transform pivot = (UseMoonPivot && MoonOrbitPivot != null) ? MoonOrbitPivot : transform;
|
||||
Matrix4x4 localToWorld = pivot.localToWorldMatrix;
|
||||
Vector3 worldDirection = localToWorld.MultiplyVector(localDirection);
|
||||
Sky.MoonLightSource.transform.forward = worldDirection;
|
||||
Sky.MoonLightSource.color = Sky.Profile.Material.GetColor(JMat.MOON_LIGHT_COLOR);
|
||||
Sky.MoonLightSource.intensity = Sky.Profile.Material.GetFloat(JMat.MOON_LIGHT_INTENSITY);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateEnvironmentReflection()
|
||||
{
|
||||
if ((SystemInfo.copyTextureSupport & CopyTextureSupport.RTToTexture) != 0)
|
||||
{
|
||||
if (EnvironmentProbe.texture == null)
|
||||
{
|
||||
probeRenderId = EnvironmentProbe.RenderProbe();
|
||||
}
|
||||
else if (EnvironmentProbe.texture != null || EnvironmentProbe.IsFinishedRendering(probeRenderId))
|
||||
{
|
||||
Graphics.CopyTexture(EnvironmentProbe.texture, EnvironmentReflection as Texture);
|
||||
RenderSettings.customReflection = EnvironmentReflection;
|
||||
RenderSettings.defaultReflectionMode = DefaultReflectionMode.Custom;
|
||||
probeRenderId = EnvironmentProbe.RenderProbe();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,130 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System;
|
||||
|
||||
namespace Pinwheel.Jupiter
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.InitializeOnLoad]
|
||||
#endif
|
||||
[CreateAssetMenu(menuName = "Jupiter/Day Night Cycle Profile")]
|
||||
public class JDayNightCycleProfile : ScriptableObject
|
||||
{
|
||||
private static Dictionary<string, int> propertyRemap;
|
||||
private static Dictionary<string, int> PropertyRemap
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propertyRemap == null)
|
||||
{
|
||||
propertyRemap = new Dictionary<string, int>();
|
||||
}
|
||||
return propertyRemap;
|
||||
}
|
||||
set
|
||||
{
|
||||
propertyRemap = value;
|
||||
}
|
||||
}
|
||||
|
||||
static JDayNightCycleProfile()
|
||||
{
|
||||
InitPropertyRemap();
|
||||
}
|
||||
|
||||
private static void InitPropertyRemap()
|
||||
{
|
||||
PropertyRemap.Clear();
|
||||
Type type = typeof(JSkyProfile);
|
||||
PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||
foreach (PropertyInfo p in props)
|
||||
{
|
||||
JAnimatableAttribute animatable = p.GetCustomAttribute(typeof(JAnimatableAttribute), false) as JAnimatableAttribute;
|
||||
if (animatable == null)
|
||||
continue;
|
||||
string name = p.Name;
|
||||
int id = Shader.PropertyToID("_" + name);
|
||||
PropertyRemap.Add(name, id);
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private List<JAnimatedProperty> animatedProperties;
|
||||
public List<JAnimatedProperty> AnimatedProperties
|
||||
{
|
||||
get
|
||||
{
|
||||
if (animatedProperties == null)
|
||||
{
|
||||
animatedProperties = new List<JAnimatedProperty>();
|
||||
}
|
||||
return animatedProperties;
|
||||
}
|
||||
set
|
||||
{
|
||||
animatedProperties = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddProperty(JAnimatedProperty p, bool setDefaultValue = true)
|
||||
{
|
||||
if (setDefaultValue)
|
||||
{
|
||||
JDayNightCycleProfile defaultProfile = JJupiterSettings.Instance.DefaultDayNightCycleProfile;
|
||||
if (defaultProfile != null)
|
||||
{
|
||||
JAnimatedProperty defaultProp = defaultProfile.AnimatedProperties.Find(p0 => p0.Name != null && p0.Name.Equals(p.Name));
|
||||
if (defaultProp != null)
|
||||
{
|
||||
p.Curve = defaultProp.Curve;
|
||||
p.Gradient = defaultProp.Gradient;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnimatedProperties.Add(p);
|
||||
}
|
||||
|
||||
public void Animate(JSky sky, float t)
|
||||
{
|
||||
CheckDefaultProfileAndThrow(sky.Profile);
|
||||
|
||||
for (int i = 0; i < AnimatedProperties.Count; ++i)
|
||||
{
|
||||
JAnimatedProperty aProp = AnimatedProperties[i];
|
||||
int id = 0;
|
||||
if (!PropertyRemap.TryGetValue(aProp.Name, out id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (aProp.CurveOrGradient == JCurveOrGradient.Curve)
|
||||
{
|
||||
sky.Profile.Material.SetFloat(id, aProp.EvaluateFloat(t));
|
||||
}
|
||||
else
|
||||
{
|
||||
sky.Profile.Material.SetColor(id, aProp.EvaluateColor(t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckDefaultProfileAndThrow(JSkyProfile p)
|
||||
{
|
||||
if (p == null)
|
||||
return;
|
||||
if (p == JJupiterSettings.Instance.DefaultProfileSunnyDay ||
|
||||
p == JJupiterSettings.Instance.DefaultProfileStarryNight)
|
||||
{
|
||||
throw new ArgumentException("Animating default sky profile is prohibited. You must create a new profile for your sky to animate it.");
|
||||
}
|
||||
}
|
||||
|
||||
public bool ContainProperty(string propertyName)
|
||||
{
|
||||
return AnimatedProperties.Exists((p) => p.Name.Equals(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user