Melchior FRANZ:
Re-organisation: <diffuse>, <ambient>, <emission>, <specular> are now groups with members <red>, <green>, <blue>, <factor>, <offset>, and their <*-prop> forms. Additionally, there's an option <property-base> that can be used to set a path that is prepended to all <*-prop> paths. It defaults to an empty string. Rationale: see model-howto.html.
This commit is contained in:
parent
4718f2f8f0
commit
d0f032bf73
2 changed files with 126 additions and 54 deletions
|
@ -905,38 +905,89 @@ display explains the format clearly:</p>
|
|||
|
||||
<h3><a name="material">"material" animation type</a></h3>
|
||||
<p>This "animation" can set any of the material properties on a model branch, including
|
||||
the texture file path. A simple case for such an animation can look like this:</p>
|
||||
the texture file path. The following minimalistic example animation allows to change the
|
||||
"panel" object's emissive color from (0,0,0) to (1,.2,0) by setting the factor property
|
||||
to values between 0.0 and 1.0.</p>
|
||||
|
||||
<blockquote>
|
||||
<pre><animation>
|
||||
<type>material</type>
|
||||
<object-name>panel</object-name>
|
||||
<emission>
|
||||
<red>1.0</red>
|
||||
<green>0.2</green>
|
||||
<blue>0.0</blue>
|
||||
<factor-prop>/controls/lighting/instruments-norm</factor-prop>
|
||||
</emission>
|
||||
</animation>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
|
||||
<p>Changes made with this animation type are by default only effective for the objects listed in
|
||||
<object-name> tags, whereby you can use more than one of those. The next example, however,
|
||||
sets the optional <global> property, so that changes affect all objects that share
|
||||
the same material. This is the preferred method and should be used whereever possible. It isn't
|
||||
only faster, but also doesn't break other animations by forcing objects into the same branch.
|
||||
Note that all material properties can be set to fixed values, for instance <red> or, by appending
|
||||
"-prop", to the contents of another property node: <red-prop>. Because a "material" animation
|
||||
can contain a lot of such property paths, which is a nuisance to write, hard to read, and a potential
|
||||
source for typos, there's a <property-base> component. Its string value is prepended to
|
||||
all material property names (but not to property paths in a <condition> statement!).
|
||||
The following example shows all available elements:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre><animation>
|
||||
<type>material</type>
|
||||
<object-name>fuselage</object-name>
|
||||
<condition>
|
||||
<property>/sim/model/foo/animate-fuselage-material</property>
|
||||
</condition>
|
||||
<global type="bool">true</global>
|
||||
<emission-red>1.0</emission-red>
|
||||
<emission-green>0.8</emission-green>
|
||||
<emission-blue>0.3</emission-blue>
|
||||
<emission-factor-prop>/controls/lighting/instruments-norm</emission-factor-prop>
|
||||
<emission-offset>0.3</emission-offset>
|
||||
<property-base>/sim/model/foo/material/fuselage</property-base>
|
||||
<diffuse>
|
||||
<red-prop>diffuse/red</red-prop>
|
||||
<green-prop>diffuse/green</green-prop>
|
||||
<blue-prop>diffuse/blue</blue-prop>
|
||||
<factor-prop>diffuse/factor</factor-prop>
|
||||
<offset-prop>diffuse/offset</offset-prop>
|
||||
</diffuse>
|
||||
<ambient>
|
||||
<red-prop>ambient/red</red-prop>
|
||||
<green-prop>ambient/green</green-prop>
|
||||
<blue-prop>ambient/blue</blue-prop>
|
||||
<factor-prop>ambient/factor</factor-prop>
|
||||
<offset-prop>ambient/offset</offset-prop>
|
||||
</ambient>
|
||||
<emission>
|
||||
<red-prop>emission/red</red-prop>
|
||||
<green-prop>emission/green</green-prop>
|
||||
<blue-prop>emission/blue</blue-prop>
|
||||
<factor-prop>emission/factor</factor-prop>
|
||||
<offset-prop>emission/offset</offset-prop>
|
||||
</emission>
|
||||
<specular>
|
||||
<red-prop>specular/red</red-prop>
|
||||
<green-prop>specular/green</green-prop>
|
||||
<blue-prop>specular/blue</blue-prop>
|
||||
<factor-prop>specular/factor</factor-prop>
|
||||
<offset-prop>specular/offset</offset-prop>
|
||||
</specular>
|
||||
<shininess>shininess</shininess>
|
||||
<transparency>transparency</transparency>
|
||||
<texture>texture</texture>
|
||||
<threshold>threshold</threshold>
|
||||
</animation>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>The change is only effective for the objects listed in "object-name" tags,
|
||||
whereby you can use more than one of those. The above example, however,
|
||||
sets the optional "global" property, so that the changes affect all objects that share
|
||||
the same material. Note that all material properties can be set to fixed
|
||||
values or, by appending "-prop", to the contents of another property node.</p>
|
||||
|
||||
<p>The "emission" group is only one of four available groups: "diffuse,
|
||||
"ambient", "specular, and "emission". A change to one of the components
|
||||
in each group does always update all three color components. Unset values
|
||||
default to zero. In addition to the color groups there are three properties
|
||||
"shininess", "transparency", "threshold", and "texture". The "texture" path
|
||||
is relative to the "texture-path" target or, if unset, the model directory.
|
||||
All numerical values are clamped to 0.0-1.0, except "shininess", which is
|
||||
clamped to 0.0-128.0. The "transparency" property makes an object fully
|
||||
transparent (and thus invisible) with 0.0, and fully opaque with 1.0. The
|
||||
"threshold" property sets the opaqueness threshold. It is only relevant for
|
||||
<p>A change to one of the components in each color group does always update
|
||||
all three color components. Unset values default to zero. The <texture> path
|
||||
is relative to the model's <texture-path> directory, or, if unset, to the model
|
||||
directory. All numerical values are clamped to 0.0-1.0, except <shininess>, which is
|
||||
clamped to 0.0-128.0. The <transparency> property makes an object fully
|
||||
transparent (and thus invisible) with 1.0, and fully opaque with 0.0. The
|
||||
<threshold> property sets the opaqueness threshold. It is only relevant for
|
||||
semitransparent textures. Only parts of the texture that are more opaque
|
||||
than this are diplayed at all. If it is set to 0.0, all parts of the texture
|
||||
will be shown. If it is 0.5, only parts with opaqueness greater than 0.5
|
||||
|
@ -944,7 +995,7 @@ will be shown. If it is 0.5, only parts with opaqueness greater than 0.5
|
|||
|
||||
<p>Note that defining two or more of these animations for the same object,
|
||||
or a mixture of "material" and "blend" animations, will probably not yield
|
||||
the result that you expect. Try to do all state manipulations for one
|
||||
the result that you expect. Try to put all state manipulations for one
|
||||
object or material in one "material" animation, and use its "transparency"
|
||||
property instead of an extra "blend" animation.</p>
|
||||
|
||||
|
@ -973,6 +1024,17 @@ like this:</p>
|
|||
</pre>
|
||||
</blockquote>
|
||||
|
||||
|
||||
<p>You can explore the influence of material changes at runtime, if you use
|
||||
a material animation like the above complete example, and call the material
|
||||
dialog on it, like in the following Nasal example. Note, that the path is
|
||||
the same that you would set in <property-base>.
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>material.showDialog("/sim/model/foo/material/fuselage");</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
<address>David Megginson, 11 March 2002</address>
|
||||
|
||||
|
|
|
@ -4,18 +4,22 @@
|
|||
# Usage: material.showDialog(<path>, [<title>], [<x>], [<y>]);
|
||||
#
|
||||
# the path should point to a property "directory" (usually set in
|
||||
# the aircraft's *-set.xml file) that contains any of:
|
||||
# the aircraft's *-set.xml file) that contains any of
|
||||
# (shininess|transparency|texture) and (diffuse|ambient|specular|emission),
|
||||
# whereby the latter four are directories containing any of
|
||||
# (red|green|blue|factor|offset).
|
||||
#
|
||||
# {diffuse,ambient,specular,emission}-{red,green,blue,factor,offset}
|
||||
# shininess, transparency, texture
|
||||
#
|
||||
# If <title> is omitted, then the last path component is used as title.
|
||||
# If <title> is omitted or nil, then the last path component is used as title.
|
||||
# If <x> and <y> are undefined, then the dialog is centered.
|
||||
#
|
||||
#
|
||||
# Example:
|
||||
# <foo>
|
||||
# <diffuse-red>1.0</diffuse-red>
|
||||
# <diffuse>
|
||||
# <red>1.0</red>
|
||||
# <green>0.5</green>
|
||||
# <blue>0.5</blue>
|
||||
# </diffuse>
|
||||
# <transparency>0.5</transparency>
|
||||
# <texture>bar.rgb</texture>
|
||||
# </foo>
|
||||
|
@ -33,31 +37,36 @@
|
|||
# <animation>
|
||||
# <type>material</type>
|
||||
# <object-name>foo</object-name>
|
||||
# <diffuse-red-prop>/foo/diffuse-red</diffuse-red-prop>
|
||||
# <transparency-prop>/foo/transparency</transparency-prop>
|
||||
# <texture-prop>/foo/texture</texture-prop>
|
||||
# <property-base>/sim/model/foo</property-base>
|
||||
# <diffuse>
|
||||
# <red-prop>diffuse/red</red-prop>
|
||||
# <green-prop>diffuse/green</green-prop>
|
||||
# <blue-prop>diffuse/blue</blue-prop>
|
||||
# </diffuse>
|
||||
# <transparency-prop>transparency</transparency-prop>
|
||||
# <texture-prop>texture</texture-prop>
|
||||
# </animation>
|
||||
#
|
||||
|
||||
dialog = nil;
|
||||
|
||||
colorgroup = func {
|
||||
parent = arg[0];
|
||||
name = arg[1];
|
||||
parent = arg[0]; # pui parent
|
||||
name = arg[1]; # "diffuse"
|
||||
base = arg[2];
|
||||
undef = func { props.globals.getNode(base ~ name ~ "-" ~ arg[0]) == nil };
|
||||
undef = func { props.globals.getNode(base ~ name ~ "/" ~ arg[0]) == nil };
|
||||
|
||||
if (undef("red") and undef("green") and undef("blue")) {
|
||||
return;
|
||||
}
|
||||
grp = parent.addChild("group");
|
||||
grp.set("layout", "hbox");
|
||||
grp.addChild("text").set("label", "-- " ~ name ~ " --");
|
||||
grp.addChild("text").set("label", "_______" ~ name ~ "_______");
|
||||
|
||||
foreach (color; ["red", "green", "blue", "factor"]) {
|
||||
mat(parent, color, base ~ name ~ "-" ~ color);
|
||||
mat(parent, color, base ~ name ~ "/" ~ color, "%.3f");
|
||||
}
|
||||
mat(parent, "offset", base ~ name ~ "-" ~ "offset", -1.0, 1.0);
|
||||
mat(parent, "offset", base ~ name ~ "/" ~ "offset", "%.3f", -1.0, 1.0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -65,6 +74,7 @@ mat = func {
|
|||
parent = arg[0];
|
||||
name = arg[1];
|
||||
path = arg[2];
|
||||
format = arg[3];
|
||||
if (props.globals.getNode(path) != nil) {
|
||||
grp = parent.addChild("group");
|
||||
grp.set("layout", "hbox");
|
||||
|
@ -75,14 +85,15 @@ mat = func {
|
|||
slider = grp.addChild("slider");
|
||||
slider.set("property", path);
|
||||
slider.set("live", 1);
|
||||
if (size(arg) == 5) {
|
||||
slider.set("min", arg[3]);
|
||||
slider.set("max", arg[4]);
|
||||
if (size(arg) == 6) {
|
||||
slider.set("min", arg[4]);
|
||||
slider.set("max", arg[5]);
|
||||
}
|
||||
slider.prop().getNode("binding[0]/command", 1).setValue("dialog-apply");
|
||||
|
||||
number = grp.addChild("text");
|
||||
number.set("label", "-0.1234567");
|
||||
number.set("label", "-0.123");
|
||||
number.set("format", format);
|
||||
number.set("property", path);
|
||||
number.set("live", 1);
|
||||
}
|
||||
|
@ -115,7 +126,7 @@ showDialog = func {
|
|||
|
||||
titlebar = dialog.addChild("group");
|
||||
titlebar.set("layout", "hbox");
|
||||
titlebar.addChild("text").set("label", title);
|
||||
titlebar.addChild("text").set("label", "[" ~ title ~ "]");
|
||||
titlebar.addChild("empty").set("stretch", 1);
|
||||
|
||||
w = titlebar.addChild("button");
|
||||
|
@ -123,34 +134,33 @@ showDialog = func {
|
|||
w.set("pref-height", 16);
|
||||
w.set("legend", "");
|
||||
w.set("default", 1);
|
||||
w.prop().getNode("binding[0]/command", 1).setValue("dialog-apply");
|
||||
w.prop().getNode("binding[1]/command", 1).setValue("dialog-close");
|
||||
|
||||
colorgroup(dialog, "diffuse", base);
|
||||
colorgroup(dialog, "ambient", base);
|
||||
colorgroup(dialog, "specular", base);
|
||||
colorgroup(dialog, "emission", base);
|
||||
colorgroup(dialog, "specular", base);
|
||||
|
||||
undef = func { props.globals.getNode(base ~ arg[0]) == nil };
|
||||
if (!(undef("shininess") and undef("transparency") and undef("threshold"))) {
|
||||
w = dialog.addChild("group");
|
||||
w.set("layout", "hbox");
|
||||
w.addChild("text").set("label", "-- misc --");
|
||||
w.addChild("text").set("label", "_________misc_________");
|
||||
|
||||
mat(dialog, "shi", base ~ "shininess", 0.0, 128.0);
|
||||
mat(dialog, "trans", base ~ "transparency");
|
||||
mat(dialog, "thresh", base ~ "threshold");
|
||||
mat(dialog, "shi", base ~ "shininess", "%.0f", 0.0, 128.0);
|
||||
mat(dialog, "trans", base ~ "transparency", "%.3f");
|
||||
mat(dialog, "thresh", base ~ "threshold", "%.3f");
|
||||
}
|
||||
|
||||
path = base ~ "texture";
|
||||
if (props.globals.getNode(path) != nil) {
|
||||
if (!undef("texture")) {
|
||||
w = dialog.addChild("group");
|
||||
w.set("layout", "hbox");
|
||||
w.addChild("text").set("label", "-- texture --");
|
||||
w.addChild("text").set("label", "_______texture_______");
|
||||
|
||||
w = dialog.addChild("input");
|
||||
w.set("pref-width", 250);
|
||||
w.set("property", path);
|
||||
w.set("live", 1);
|
||||
w.set("pref-width", 200);
|
||||
w.set("property", base ~ "texture");
|
||||
w.prop().getNode("binding[0]/command", 1).setValue("dialog-apply");
|
||||
}
|
||||
dialog.addChild("empty").set("pref-height", "3");
|
||||
|
|
Loading…
Reference in a new issue