/// <summary> /// Register the vertex lit object to receive Light calculations. It is also immediately painted to avoid it showing at an off color in the first frame. /// </summary> /// <param name="obj">Object to register.</param> public static void RegisterVertexLitObject(VertexLitObject obj) { if (_data == null) { SetupData(); } if (_data.Config == null) { //This needs to be done here because objects can try to register themselves before //this script's Setup has been ran... and it is impossible to guarantee the order. if (_data.QueuedLitObjects == null) { _data.QueuedLitObjects = new List <VertexLitObject>(50); _data.QueuedLitObjectsCount = 0; } _data.QueuedLitObjects.Add(obj); _data.QueuedLitObjectsCount++; return; } _data.LitObjects.Add(obj); _data.LitObjectsCount++; ForcePaint(obj); }
/// <summary> /// Effectively paints the object vertex colors to the new desired color. Takes into consideration light positions, /// checks if new color is too close to old color, checks if character has some kind of abnormal color to apply, /// and finally sets all vertex colors to all meshes of this object. If IgnoreProximity is set to true, object will be /// painted regardless of any conditions. /// </summary> /// <param name="obj">The object to paint.</param> /// <param name="ignoreProximity">If set to <c>true</c>, forces object to be painted.</param> private static void Paint(VertexLitObject obj, bool ignoreProximity = false) { var color = _data.AmbientColor; if (obj.HasAbnormalEffectColor) { color = obj.AbnormalEffectColor; } for (var i = 0; i < _data.LightsCount; i++) { var lightObj = _data.Lights[i]; var distance = (obj.transform.position - lightObj.Position).sqrMagnitude; var radius = lightObj.SqrRadius; if (distance > radius) { continue; } var result = 1 - (distance / radius); color = Color32.Lerp(color, lightObj.Color, result); } if (!obj.IgnoreColorProximityChecks && !ignoreProximity && Mathf.Abs(color.r - obj.LastColor.r) < _data.ProximityLevel && Mathf.Abs(color.g - obj.LastColor.g) < _data.ProximityLevel && Mathf.Abs(color.b - obj.LastColor.b) < _data.ProximityLevel && obj.ColorMultiplier <= 0.2f) { return; } color.r = (byte)(color.r * obj.ColorMultiplier); color.g = (byte)(color.g * obj.ColorMultiplier); color.b = (byte)(color.b * obj.ColorMultiplier); obj.LastColor = color; obj.LastUpdatedPosition = obj.transform.position; for (var i = 0; i < obj.MeshFiltersLength; i++) { var objColor = obj.Colors[i]; for (var j = 0; j < objColor.ColorsLength; j++) { objColor.Colors[j] = color; } if (obj.MeshFilters[i] != null) { #if UNTOLD_DEBUG if (obj.MeshFilters[i].mesh.vertices.Length != objColor.Colors.Length) { Debug.LogError("THE OBJ HAS NOT BEEN BAKED! [click me]", obj); } #endif obj.MeshFilters[i].mesh.colors32 = objColor.Colors; } } }
/// <summary> /// Once unregistered, this object's color will not receive any further light calculations. /// </summary> /// <param name="obj">Object to unregister.</param> public static void UnregisterVertexLitObject(VertexLitObject obj) { //This is necessary because objects can unregister themselves after Release has been called. if (_data.LitObjects == null) { return; } _data.LitObjects.Remove(obj); _data.LitObjectsCount--; }
/// <summary> /// Can be called to force an object to be painted regardless of anything else. Should be used only when certain object /// has been updated dynamically and is already registered but waiting to be repainted (frame delay). Example of usage is /// the ModelEquipmentSwitcher, when the user clicks on a different weapon on the Recipes screen, and the model is updated. /// </summary> /// <param name="obj">Vertex Lit Object.</param> public static void ForcePaint(VertexLitObject obj) { obj.FrameToUpdate = _data.CurrentFrameCount + 10; Paint(obj, true); }