|
|
Line 1: |
Line 1: |
| <languages></languages>
| | The '''data model''' refers to the declaration, structure, and handling of [[types]], data, and changes on data within [[FrooxEngine]]. The data model allows for change detection, value synchronization, unified structure, and serialization of any and all types that FrooxEngine encounters. |
|
| |
|
| {{Infobox Component
| | == Elements == |
| |Image=ValueGradientDriver`1Component.png
| |
| |Name=ValueGradientDriver
| |
| }}
| |
|
| |
|
| <translate>
| | Everything that gets managed by the data model in some fashion implements the [[Type:IWorldElement|IWorldElement]] interface. This interface assigns elements with a host of properties, including a [[Type:RefID|reference ID]], possible parent element, and whether the element is persistent or not. |
| <!--T:1-->
| |
| The '''ValueGradientDriver''' component changes the value of the field defined in <code>Target</code> based on the items in the <code>Points</code> list and their <code>Position</code> in relation to the <code>Progress</code> value.
| |
| </translate>
| |
|
| |
|
| == <translate><!--T:2--> Fields</translate> ==
| | This interface doesn't have much behavior by itself--it only specifies a thing as being able to be saved and loaded into [[worlds]] in some fashion. More complex behaviors offered by the data model are provided by types that implement this interface. The three types of elements that directly implement this interface are ''sync elements'', ''workers'', and ''worlds''. |
|
| |
|
| {{Table ComponentFields
| | == Sync elements == |
| |Progress|Float|<translate><!--T:3--> Controls which items from the <code>Points</code> list will be used to drive the value of <code>Target</code></translate>
| |
| |Target|{{RootFieldType|FieldDrive`1|T}}|TypeAdv1=true|<translate><!--T:4--> The field that this component will drive the value of</translate>
| |
| |Interpolate|Bool|<translate><!--T:5--> Controls whether or not this component will interpolate (or blend) between the nearest two <code>Points</code> to the current <code>Progress</code> value.</translate>
| |
| |Points|{{RootFieldType|SyncList`1|[[#Point|Point]]<T>}}|TypeAdv3=true|<translate><!--T:6--> A list of items indicating their <code>Position</code> (in relation to <code>Progress</code>), and a <code>Value</code></translate>
| |
| }}
| |
|
| |
|
| == <translate><!--T:7--> Usage</translate> ==
| | [[Type:SyncElement|Sync elements]] represent a value or object that can be written to, [[field linkage|linked]], and send/receive change events from other elements. Sync elements mainly comprise of [[Type:SyncField|fields]] and various types of collections--usually any type name that starts with <code>Sync</code> derives from a sync element. |
|
| |
|
| <translate>
| | The main thing that separates sync elements from other elements is, well, synchronization. Whenever a sync element is changed, spare few exceptions like [[Type:RawOutput`1|RawOutput<T>]], it and its entire parent hierarchy propagate a change event. This includes the elements getting put in the world's update manager to synchronize their values at the end of the update loop. |
| <!--T:8-->
| |
| Each point in the <code>Points</code> list has a <code>Position</code> field and <code>Value</code> field. The <code>Position</code> field is used for comparison with the component's <code>Progress</code> field, while the <code>Value</code> field is the value used for driving the field in <code>Target</code>.
| |
|
| |
|
| <!--T:9-->
| | == Workers == |
| When <code>Interpolate</code> is checked, the value stored in <code>Target</code> is linearly interpolated between the <code>Value</code>s of the two points surrounding the current <code>Progress</code>. When unchecked, the output value is simply set to the <code>Value</code> of the closest point before the current <code>Progress</code>. The only exception to this is when no point exists before the current <code>Progress</code>, in which case the first point after the current <code>Progress</code> is used.
| |
|
| |
|
| <!--T:10-->
| | [[Type:Worker|Workers]] |
| If two points have the same <code>Position</code>, then the point of greatest index takes priority if the value is not interpolated or if the positions are exactly equal to the current <code>Progress</code>. ''During'' interpolation, however, the point of ''least'' index takes priority.
| |
| </translate>
| |
|
| |
|
| == <translate><!--T:11--> Examples</translate> == | | === World === |
|
| |
|
| <gallery widths=560px heights=480px>
| | Each instance |
| File:component_example_ValueGradientDriver.webm|alt=<translate><!--T:12--> A ValueGradientDriver is set up with five float values. Index 0 has position 0.00 and value 0, index 1 has position 0.77 and value 2, index 2 has position 0.25 and value 4, index 3 has position 0.67 and value 6, and index 4 has position 1.00 and value 8. As progress moves from 0 to 1, the target field is linearly interpolated between the values of indices 0, 2, 3, 1, then 4. Once interpolation is unchecked, the target field is merely set to the previous index value.</translate>|<translate><!--T:13--> General usage of the component, showing interpolation and non-interpolation between five float values.</translate>
| |
| File:Component_example_ValueGradientDriver_IndexOfMax.webp|alt=<translate><!--T:14--> A ValueGradientDriver is set up with five int values. The progress is fixed at 1 and each point's value is set to its index. Interpolation is disabled. The index of the point with the greatest position is output.</translate>|<translate><!--T:15--> An unorthodox yet valid usage of the component, as way to find the index of the maximum value in a list of floats (as the <code>Position</code> values) without the need for ProtoFlux. <code>Progress</code> may be set to 0 to find the index of the minimum value as well.</translate>
| |
| </gallery>
| |
|
| |
|
| == <translate><!--T:16--> See Also</translate> == | | == Strict exclusivity == |
|
| |
|
| [[Category:Components{{#translation:}}|Value Gradient Driver`1]] | | The data model can only function without issue when everyone in a session agrees on what the data model should be. This is the reason why [[plugins]] marked as a [[How To Create Plugins/DataModelAssemblyType|core]] assembly type cause incompatible sessions with those who do not have the plugin. |
| [[Category:Generic Components{{#translation:}}|Value Gradient Driver`1]]
| |
| [[Category:Components With Nested Types{{#translation:}}|Value Gradient Driver`1]]
| |
| [[Category:Components:Transform:Drivers{{#translation:}}|Value Gradient Driver`1]] | |
Revision as of 08:03, 2 July 2025
The data model refers to the declaration, structure, and handling of types, data, and changes on data within FrooxEngine. The data model allows for change detection, value synchronization, unified structure, and serialization of any and all types that FrooxEngine encounters.
Elements
Everything that gets managed by the data model in some fashion implements the IWorldElement interface. This interface assigns elements with a host of properties, including a reference ID, possible parent element, and whether the element is persistent or not.
This interface doesn't have much behavior by itself--it only specifies a thing as being able to be saved and loaded into worlds in some fashion. More complex behaviors offered by the data model are provided by types that implement this interface. The three types of elements that directly implement this interface are sync elements, workers, and worlds.
Sync elements
Sync elements represent a value or object that can be written to, linked, and send/receive change events from other elements. Sync elements mainly comprise of fields and various types of collections--usually any type name that starts with Sync
derives from a sync element.
The main thing that separates sync elements from other elements is, well, synchronization. Whenever a sync element is changed, spare few exceptions like RawOutput<T>, it and its entire parent hierarchy propagate a change event. This includes the elements getting put in the world's update manager to synchronize their values at the end of the update loop.
Workers
Workers
World
Each instance
Strict exclusivity
The data model can only function without issue when everyone in a session agrees on what the data model should be. This is the reason why plugins marked as a core assembly type cause incompatible sessions with those who do not have the plugin.