User Tools

Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
matsys:cmat_manual:expressionsandtables [2005-10-30 20:17]
Carsten created
matsys:cmat_manual:expressionsandtables [2013-01-07 12:07] (current)
Line 14: Line 14:
     (1 + sinTable[ time*0.25 + 3 ]) / 2     (1 + sinTable[ time*0.25 + 3 ]) / 2
 </​code>​ </​code>​
-Unfortunately,​ there is also bad news: The current parser of the Ca3DE MatSys is not yet powerful enough to+Unfortunately,​ there is also bad news: The current parser of the Cafu MatSys is not yet powerful enough to
 parse expressions that use operator infix notation like the one above. parse expressions that use operator infix notation like the one above.
 Instead of ''​+'',​ ''​-'',​ ''​*'',​ ... we therefore have to use explicit prefix notation, Instead of ''​+'',​ ''​-'',​ ''​*'',​ ... we therefore have to use explicit prefix notation,
Line 46: Line 46:
   * **''​ambientLightRed''​**   * **''​ambientLightRed''​**
   * **''​ambientLightGreen''​**   * **''​ambientLightGreen''​**
-  * **''​ambientLightBlue''​** The Ca3D-Engine ​provides the color of the ambient light //that is contributed by radiosity light sources// in these variables. Therefore, almost all material definitions that are employed with //​entities//​ (e.g. player models, weapon and item models, etc.) normally use these variables so that the entity is colored according to the ambient radiosity light. Please see the ''​.cmat''​ files in ''​Games/​DeathMatch/​Materials/​Models/''​ for many examples.+  * **''​ambientLightBlue''​** The Cafu engine ​provides the color of the ambient light //that is contributed by radiosity light sources// in these variables. Therefore, almost all material definitions that are employed with //​entities//​ (e.g. player models, weapon and item models, etc.) normally use these variables so that the entity is colored according to the ambient radiosity light. Please see the ''​.cmat''​ files in ''​Games/​DeathMatch/​Materials/​Models/''​ for many examples.
  
 Tables and table look-ups are described in subsection [[#​Tables]]. Tables and table look-ups are described in subsection [[#​Tables]].
- 
  
 ===== Tables ===== ===== Tables =====
  
-A special expression is a table look-up of the form ''​$myTable[$indexExpr]'',​ where ''​$myTable''​ is the name of a table that must have been defined before use, and ''​$indexExpr''​ is another expression that determines where in ''​$myTable''​ the look-up occurs.+A special expression is a table look-up of the form ''​$myTable[$indexExpr]'',​ where ''​$myTable''​ is the name of a table that must have been defined before use, and ''​$indexExpr''​ is another expression that determines where in ''​$myTable''​ the look-up occurs. The scope of ''​$myTable''​ begins at its definition and ends at the end of the material script.
  
 Here is a simple but complete example with a table of four values: Here is a simple but complete example with a table of four values:
Line 69: Line 68:
 </​code>​ </​code>​
 As you can see, table definitions start with the keyword ''​table'',​ followed by the name of the table. As you can see, table definitions start with the keyword ''​table'',​ followed by the name of the table.
-Then come two ''​{''​s, the table data values separated by commas (arbitrarily many), and then the closing two ''​}''​s.+Then come two ''​{'' ​brackets, the table data values separated by commas (arbitrarily many), and then the closing two ''​}'' ​brackets.
  
 Note that table data values are always mapped into the range 0 to 1. Therefore, the graphical representation of ''​myTestTable''​ looks like this: Note that table data values are always mapped into the range 0 to 1. Therefore, the graphical representation of ''​myTestTable''​ looks like this:
Line 77: Line 76:
 You may wonder what you get for ''​myTestTable[x]''​ if x is smaller than 0 or greater than 0.75, or what happens if x is "​between"​ two table values. Per default, table values are infinitely repeated outside of the range 0 to 1, and linearly interpolated between two adjacent values. Therefore, ''​myTestTable''​ from the above example in fact represents the following function, graphically shown in light blue color: You may wonder what you get for ''​myTestTable[x]''​ if x is smaller than 0 or greater than 0.75, or what happens if x is "​between"​ two table values. Per default, table values are infinitely repeated outside of the range 0 to 1, and linearly interpolated between two adjacent values. Therefore, ''​myTestTable''​ from the above example in fact represents the following function, graphically shown in light blue color:
  
-{{matsys:​cmat_manual:​table_default.png?​500 }} Observe how the values repeat with each integral number, and how intermediate values are linearly interpolated<​clear>​+{{matsys:​cmat_manual:​table_default.png?​500 }} Observe how the values repeat with each integral number. That is, the table in range 0 to 1 is repeated between 1 to 2, between 2 to 3, 3 to 4, and so on. It is also repeated into the negative range, that is from -1 to 0, from -2 to -1, -3 to -2, and so on.
  
-For special-purpose tables, you can insert the keywords ''​snap''​ and/or ''​clamp''​ between the two opening ''​{''​of the table definition. ''​snap''​ turns the linear interpolation off, and instead repeats the previous value until the next table value. Thus, if we changed the definition of our ''​myTestTable''​ above to+Also observe how intermediate values are linearly interpolated. For example, the value at ''​myTestTable[0.375]''​ (in the mid between 0.25 and 0.5) yields 1.0 as the result. <​clear>​ 
 + 
 +For example, if you access ''​myTestTable''​ via the MatSys variable ''​time'',​ as in ''​myTestTable[time]'',​ then it always takes exactly one second to traverse the entire table. If you want to change the speed with which the table is traversed, then you'll have to multiply the index variable ''​time''​ with an appropriate scale factor. For example, ''​myTestTable[div(time,​ 3)]''​ will take three seconds to walk the entire table once. 
 + 
 +=== snap and clamp === 
 + 
 +For special-purpose tables, you can insert the keywords ''​snap''​ and/or ''​clamp''​ between the two opening ''​{'' ​brackets ​of the table definition. 
 + 
 +**''​snap''​** turns the linear interpolation off, and instead repeats the previous value until the next table value. Thus, if we changed the definition of our ''​myTestTable''​ above to
 <​code>​ <​code>​
     table myTestTable { snap { 0.2, 1.4, 0.6, 1 } }     table myTestTable { snap { 0.2, 1.4, 0.6, 1 } }
Line 87: Line 94:
 {{matsys:​cmat_manual:​table_snap.png?​500 }} ''​snap''​ turns the interpolation off, and just repeats one value until the next. <​clear>​ {{matsys:​cmat_manual:​table_snap.png?​500 }} ''​snap''​ turns the interpolation off, and just repeats one value until the next. <​clear>​
  
-FIXME: ​ FINISH! +Snapping is useful whenever ​you want to have table to encode ​functions ​that have "​hard"​ rather than "​smooth"​ transitionsFor example, ​in order to have LEDs flicker ​the SOS morse codeyou'd use this table:
- +
-Another type of object that you can define in material scripts are **tables**. +
-Tables are very powerful means to express arbitrary ​functions ​for use in expressions. +
-Expressions are explained ​in detail above in subsection [[#​Expressions]]. +
- +
-Table definitions start with the keyword ''​table''​followed by the name of the table. +
-Then come two ''​{''​s,​ the table data values separated by commas, and then the closing two ''​}''​s. +
-Here is an example of a table definition:+
 <​code>​ <​code>​
-    table myFlickerTable ​{ { 0.5, 1, 0, 0.2, 0.0, 0.8, 0.1, 0.7 } }+    table sosTable ​snap 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 01, 0, 1, 0, 0, 0 } }
 </​code>​ </​code>​
  
-The elements ​of tables can be accessed from expressions as explained in subsection [[#​Expressions]]. +**''​clamp''​** turns off the repetition ​of the table values ​outside ​of the range 0 to 1. That isadding ​''​clamp'' ​to our definition of ''​myTestTable'' ​yields:
-It is important to note that the indices for table access are treated as //​normalized//​ indices. +
-That means that all values of a table are accessed with numbers that are greater or equal to 0.0 and less than 1.0. +
-In the above tablewhich has eight elements, you'd get 0.5 for ''​myFlickerTable[0.0]''​, 1 for ''​myFlickerTable[0.125]'', +
-0.2 for ''​myFlickerTable[0.375]''​ and so on.+
  
-As tables normally wrap, that is, start over when you read over their end, you will get 0.5 also for ''​myFlickerTable[1.0]''​ +{{matsys:​cmat_manual:​table_clamp.png?500 }}
-(but 0.7 for ''​myFlickerTable[0.9999]''​). +
-You may want to think of this as only the fractional part of the index being taken for the look-up, while the integer part is ignored. +
-That means that for example the expression+
 <​code>​ <​code>​
-    rgb myFlickerTable[time]+ table myTestTable { clamp { 0.2, 1.4, 0.6, 1 } }
 </​code>​ </​code>​
-runs through ​the entire ​table exactly once per second//no matter how many elements ​the table actually has//.+With ''​clamp'', ​the first table value is returned for ''​myTestTable[x]''​ where x is less than 0and the last table value is returned whenever x is greater than 1 (in fact, greater than 1-1/TableSize)<​clear>​
  
-Between the two opening ''​{''​one or both of the keywords ​''​snap''​ and ''​clamp'' ​are allowed. +Finallyyou can also combine ​''​snap''​ and ''​clamp''​: 
-''​snap''​ defines that there is no linear interpolation between the table values. + 
-For example, we just said that ''​myFlickerTable[0.0]''​ yields 0.5 and ''​myFlickerTable[0.125]''​ yields 1.0. +{{matsys:​cmat_manual:​table_snap_clamp.png?500 }}
-But what does ''​myFlickerTable[0.0625]''​ (the middle between 0.0 and 0.125) yield? +
-If ''​snap''​ has not been specified, the value will automatically be interpolated between the table elements, +
-and the result would be 0.75. If however ''​snap''​ has been defined, the result would be "​snapped"​ to the next lower table element, +
-and the result would be 0.5. +
-Figure TODO demonstrates plots of two tables that differ in the use of the ''​snap''​ keyword but are identical otherwise. +
-Interpolation is useful whenever you want to have a table to encode functions that have "​smooth transitions"​. +
-Snapping is useful whenever you want to have a table to encode functions that have "hard transitions"​. +
-For example, in order to have LEDs flicker the SOS morse code, you'd use this table:+
 <​code>​ <​code>​
-    ​table sosTable ​{ snap { 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, + table myTestTable ​{ snap clamp { 0.2, 1.4, 0.6, 1 } }
-                            1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0 } }+
 </​code>​ </​code>​
 +<​clear>​
 +
 +
 +=== Predefined Tables ===
  
-The ''​clamp''​ keywords defines what happens if a table is accessed at indices outside of the normalized range 0.0 to 1.0. +Normallytables must be defined before their first usebut there are also tables that are inherently defined by the MatSys and can always be used without prior definition:
-Without ''​clamp''​the default behaviour is to wrap. +
-With clamping enabledthe indices ​are clamped to yield the smallest or greatest table element. +
-Figure FIXME TODO demonstrates plots of two tables that differ in the use of the ''​clamp''​ keyword but are identical otherwise.+
  
-Tables must be defined before their first use. +  * **''​sinTable''​** yields the sinus of its argument. Note that the entire 360° (2pi) arc is compressed into the range 0 to 1, not 0 to 2pi. 
-As an exception, the two tables ​''​sinTable'' ​and ''​cosTable'' ​are implicitly predefined and can always be used without +  * **''​cosTable''​** yields the cosinus ​of its argument. Note that the entire 360° (2pi) arc is compressed into the range 0 to 1, not 0 to 2pi
-prior declaration. +  * **''​sinTable01''​** like ''​sinTable'',​ but the values ​are not returned in range -1 to 1, but "​compressed"​ to to 1That is, ''​sinTable01[x]''​ is equivalent to ''​div(add(sinTable[x], ​1), 2)''​. 
-The scope of a table begins at its definition and ends at the end of the material script+  * **''​cosTable01''​** like ''​cosTable''​but the values ​are not returned in range -1 to 1, but "​compressed"​ to 0 to 1. That is, ''​cosTable01[x]''​ is equivalent to ''​div(add(cosTable[x],​ 1), 2)''​.
-Note that although in the above examples only table element ​values ​between ​0.0 and 1.0 occurarbitrary numbers ​are allowed.+
  
matsys/cmat_manual/expressionsandtables.1130699827.txt.gz · Last modified: 2013-01-07 12:07 (external edit)