您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
118 行
4.0 KiB
118 行
4.0 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Reflection;
|
|
using System.Linq;
|
|
|
|
namespace UnityEngine.Experimental.Rendering
|
|
{
|
|
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
|
|
public sealed class VolumeComponentMenu : Attribute
|
|
{
|
|
public readonly string menu;
|
|
// TODO: Add support for component icons
|
|
|
|
public VolumeComponentMenu(string menu)
|
|
{
|
|
this.menu = menu;
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
public class VolumeComponent : ScriptableObject
|
|
{
|
|
// Used to control the state of this override - handy to quickly turn a volume override
|
|
// on & off in the editor
|
|
public bool active = true;
|
|
|
|
internal ReadOnlyCollection<VolumeParameter> parameters { get; private set; }
|
|
|
|
protected virtual void OnEnable()
|
|
{
|
|
// Automatically grab all fields of type VolumeParameter for this instance
|
|
parameters = this.GetType()
|
|
.GetFields(BindingFlags.Public | BindingFlags.Instance)
|
|
.Where(t => t.FieldType.IsSubclassOf(typeof(VolumeParameter)))
|
|
.OrderBy(t => t.MetadataToken) // Guaranteed order
|
|
.Select(t => (VolumeParameter)t.GetValue(this))
|
|
.ToList()
|
|
.AsReadOnly();
|
|
|
|
foreach (var parameter in parameters)
|
|
parameter.OnEnable();
|
|
}
|
|
|
|
protected virtual void OnDisable()
|
|
{
|
|
if (parameters == null)
|
|
return;
|
|
|
|
foreach (var parameter in parameters)
|
|
parameter.OnDisable();
|
|
}
|
|
|
|
// You can override this to do your own blending. Either loop through the `parameters` list
|
|
// or reference direct fields (you'll need to cast `state` to your custom type and don't
|
|
// forget to use `SetValue` on parameters, do not assign directly to the state object - and
|
|
// of course you'll need to check for the `overrideState` manually).
|
|
public virtual void Override(VolumeComponent state, float interpFactor)
|
|
{
|
|
int count = parameters.Count;
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
var stateParam = state.parameters[i];
|
|
var toParam = parameters[i];
|
|
|
|
// Keep track of the override state for debugging purpose
|
|
stateParam.overrideState = toParam.overrideState;
|
|
|
|
if (toParam.overrideState)
|
|
stateParam.Interp(stateParam, toParam, interpFactor);
|
|
}
|
|
}
|
|
|
|
public void SetAllOverridesTo(bool state)
|
|
{
|
|
SetAllOverridesTo(parameters, state);
|
|
}
|
|
|
|
void SetAllOverridesTo(IEnumerable<VolumeParameter> enumerable, bool state)
|
|
{
|
|
foreach (var prop in enumerable)
|
|
{
|
|
prop.overrideState = state;
|
|
var t = prop.GetType();
|
|
|
|
if (VolumeParameter.IsObjectParameter(t))
|
|
{
|
|
// This method won't be called a lot but this is sub-optimal, fix me
|
|
var innerParams = (ReadOnlyCollection<VolumeParameter>)
|
|
t.GetProperty("parameters", BindingFlags.NonPublic | BindingFlags.Instance)
|
|
.GetValue(prop, null);
|
|
|
|
if (innerParams != null)
|
|
SetAllOverridesTo(innerParams, state);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Custom hashing function used to compare the state of settings (it's not meant to be
|
|
// unique but to be a quick way to check if two setting sets have the same state or not).
|
|
// Hash collision rate should be pretty low.
|
|
public override int GetHashCode()
|
|
{
|
|
unchecked
|
|
{
|
|
//return parameters.Aggregate(17, (i, p) => i * 23 + p.GetHash());
|
|
|
|
int hash = 17;
|
|
|
|
foreach (var p in parameters)
|
|
hash = hash * 23 + p.GetHashCode();
|
|
|
|
return hash;
|
|
}
|
|
}
|
|
}
|
|
}
|