Merge branch 'next' of https://git.code.sf.net/p/flightgear/fgdata into next
|
@ -400,6 +400,25 @@ See README.materials for details on configuring the random building parameters.
|
||||||
|
|
||||||
The referenced <filename> (in the example buildings.txt) contains lines of the form
|
The referenced <filename> (in the example buildings.txt) contains lines of the form
|
||||||
|
|
||||||
|
X Y Z R B W D H P S O F T
|
||||||
|
|
||||||
|
Where:
|
||||||
|
- X,Y,Z are the cartesian coordinates of the center of the front face. +X is East, +Y is North
|
||||||
|
- R is the building rotation in degrees centered on the middle of the front face.
|
||||||
|
- B is the building type [0, 1, 2] for SMALL, MEDIUM, LARGE
|
||||||
|
- W is the building width in meters
|
||||||
|
- D is the building depth in meters
|
||||||
|
- H is the building height in meters, excluding any pitched roof
|
||||||
|
- P is the pitch height in meters. 0 for a flat roof
|
||||||
|
- S is the roof shape (currently unused - all roofs are flat or gabled depending on pitch height) :
|
||||||
|
0=flat 1=skillion 2=gabled 3=half-hipped 4=hipped 5=pyramidal 6=gambled
|
||||||
|
7=mansard 8=dome 9=onion 10=round 11=saltbox
|
||||||
|
- O is the roof ridge orientation (currently unused, all roofs are assumed orthogonal) :
|
||||||
|
0 = parallel to the front face of the building
|
||||||
|
1 = orthogonal to the front face of the building
|
||||||
|
- F is the number of floors (integer)
|
||||||
|
- T is the texture index to use (integer). Buildings with the same T value will have the same texture assigned. There are 6 small, 6 medium and 4 large textures.
|
||||||
|
|
||||||
<x> <y> <z> <rot> <type>
|
<x> <y> <z> <rot> <type>
|
||||||
|
|
||||||
where :
|
where :
|
||||||
|
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 816 KiB |
|
@ -7,7 +7,7 @@
|
||||||
<type>2d</type>
|
<type>2d</type>
|
||||||
<image>Textures/buildings.png</image>
|
<image>Textures/buildings.png</image>
|
||||||
<filter>linear-mipmap-linear</filter>
|
<filter>linear-mipmap-linear</filter>
|
||||||
<wrap-s>clamp</wrap-s>
|
<wrap-s>repeat</wrap-s>
|
||||||
<wrap-t>clamp</wrap-t>
|
<wrap-t>clamp</wrap-t>
|
||||||
<internal-format>normalized</internal-format>
|
<internal-format>normalized</internal-format>
|
||||||
</texture>
|
</texture>
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
<image>Textures/buildings-normalmap_orig.png</image>
|
<image>Textures/buildings-normalmap_orig.png</image>
|
||||||
<type>2d</type>
|
<type>2d</type>
|
||||||
<filter>linear-mipmap-linear</filter>
|
<filter>linear-mipmap-linear</filter>
|
||||||
<wrap-s>clamp</wrap-s>
|
<wrap-s>repeat</wrap-s>
|
||||||
<wrap-t>clamp</wrap-t>
|
<wrap-t>clamp</wrap-t>
|
||||||
<internal-format>normalized</internal-format>
|
<internal-format>normalized</internal-format>
|
||||||
</texture>
|
</texture>
|
||||||
|
@ -63,6 +63,12 @@
|
||||||
<negative-z>Aircraft/Generic/Effects/CubeMaps/buildings/D.png</negative-z>
|
<negative-z>Aircraft/Generic/Effects/CubeMaps/buildings/D.png</negative-z>
|
||||||
</images>
|
</images>
|
||||||
</texture>
|
</texture>
|
||||||
|
<texture n="6">
|
||||||
|
<!-- instance information from shader -->
|
||||||
|
<type>2d</type>
|
||||||
|
<wrap-s>clamp</wrap-s>
|
||||||
|
<wrap-t>clamp</wrap-t>
|
||||||
|
</texture>
|
||||||
<!--Ambient correction -->
|
<!--Ambient correction -->
|
||||||
<ambient-correction type="float"> 0.0 </ambient-correction>
|
<ambient-correction type="float"> 0.0 </ambient-correction>
|
||||||
<dirt-enabled type="int"> 0 </dirt-enabled>
|
<dirt-enabled type="int"> 0 </dirt-enabled>
|
||||||
|
@ -169,27 +175,27 @@
|
||||||
<color-mask type="vec4d">0 0 0 0</color-mask>
|
<color-mask type="vec4d">0 0 0 0</color-mask>
|
||||||
</pass>-->
|
</pass>-->
|
||||||
<pass>
|
<pass>
|
||||||
<texture-unit n="4">
|
<texture-unit n="4">
|
||||||
<unit>4</unit>
|
<unit>4</unit>
|
||||||
<image>
|
<image>
|
||||||
<use>texture[3]/image</use>
|
<use>texture[3]/image</use>
|
||||||
</image>
|
</image>
|
||||||
<type>
|
<type>
|
||||||
<use>texture[3]/type</use>
|
<use>texture[3]/type</use>
|
||||||
</type>
|
</type>
|
||||||
<filter>
|
<filter>
|
||||||
<use>texture[3]/filter</use>
|
<use>texture[3]/filter</use>
|
||||||
</filter>
|
</filter>
|
||||||
<wrap-s>
|
<wrap-s>
|
||||||
<use>texture[3]/wrap-s</use>
|
<use>texture[3]/wrap-s</use>
|
||||||
</wrap-s>
|
</wrap-s>
|
||||||
<wrap-t>
|
<wrap-t>
|
||||||
<use>texture[3]/wrap-t</use>
|
<use>texture[3]/wrap-t</use>
|
||||||
</wrap-t>
|
</wrap-t>
|
||||||
<internal-format>
|
<internal-format>
|
||||||
<use>texture[3]/internal-format</use>
|
<use>texture[3]/internal-format</use>
|
||||||
</internal-format>
|
</internal-format>
|
||||||
</texture-unit>
|
</texture-unit>
|
||||||
<program>
|
<program>
|
||||||
<vertex-shader n="0">Shaders/building-model-ALS-ultra.vert</vertex-shader>
|
<vertex-shader n="0">Shaders/building-model-ALS-ultra.vert</vertex-shader>
|
||||||
<!--<fragment-shader n="0">Shaders/model-ALS-ultra.frag</fragment-shader>
|
<!--<fragment-shader n="0">Shaders/model-ALS-ultra.frag</fragment-shader>
|
||||||
|
@ -197,6 +203,22 @@
|
||||||
<fragment-shader n="2">Shaders/hazes.frag</fragment-shader>
|
<fragment-shader n="2">Shaders/hazes.frag</fragment-shader>
|
||||||
<fragment-shader n="3">Shaders/secondary_lights.frag</fragment-shader>
|
<fragment-shader n="3">Shaders/secondary_lights.frag</fragment-shader>
|
||||||
<fragment-shader n="4">Shaders/filters-ALS.frag</fragment-shader>-->
|
<fragment-shader n="4">Shaders/filters-ALS.frag</fragment-shader>-->
|
||||||
|
<attribute>
|
||||||
|
<name>instancePosition</name>
|
||||||
|
<index>10</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>instanceScaleRotate</name>
|
||||||
|
<index>11</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>rotPitchTex0x</name>
|
||||||
|
<index>12</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>tex0yTex1xTex1y</name>
|
||||||
|
<index>13</index>
|
||||||
|
</attribute>
|
||||||
</program>
|
</program>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
@ -249,6 +271,17 @@
|
||||||
<use>texture[0]/internal-format</use>
|
<use>texture[0]/internal-format</use>
|
||||||
</internal-format>
|
</internal-format>
|
||||||
</texture-unit>
|
</texture-unit>
|
||||||
|
<texture-unit>
|
||||||
|
<unit>1</unit>
|
||||||
|
<image><use>texture[6]/image</use></image>
|
||||||
|
<type><use>texture[6]/type</use></type>
|
||||||
|
<filter><use>texture[6]/filter</use></filter>
|
||||||
|
<wrap-s><use>texture[6]/wrap-s</use></wrap-s>
|
||||||
|
<wrap-t><use>texture[6]/wrap-t</use></wrap-t>
|
||||||
|
<internal-format>
|
||||||
|
<use>texture[6]/internal-format</use>
|
||||||
|
</internal-format>
|
||||||
|
</texture-unit>
|
||||||
<program>
|
<program>
|
||||||
<!--<vertex-shader n="0">Shaders/include_fog.vert</vertex-shader>-->
|
<!--<vertex-shader n="0">Shaders/include_fog.vert</vertex-shader>-->
|
||||||
<!--<vertex-shader n="1">Shaders/building-default.vert</vertex-shader>-->
|
<!--<vertex-shader n="1">Shaders/building-default.vert</vertex-shader>-->
|
||||||
|
@ -256,12 +289,33 @@
|
||||||
<fragment-shader>Shaders/trivial.frag</fragment-shader>
|
<fragment-shader>Shaders/trivial.frag</fragment-shader>
|
||||||
<!--<fragment-shader n="0">Shaders/include_fog.frag</fragment-shader>
|
<!--<fragment-shader n="0">Shaders/include_fog.frag</fragment-shader>
|
||||||
<fragment-shader n="1">Shaders/terrain-nocolor.frag</fragment-shader>-->
|
<fragment-shader n="1">Shaders/terrain-nocolor.frag</fragment-shader>-->
|
||||||
|
<attribute>
|
||||||
|
<name>instancePosition</name>
|
||||||
|
<index>10</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>instanceScaleRotate</name>
|
||||||
|
<index>11</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>rotPitchTex0x</name>
|
||||||
|
<index>12</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>tex0yTex1xTex1y</name>
|
||||||
|
<index>13</index>
|
||||||
|
</attribute>
|
||||||
</program>
|
</program>
|
||||||
<uniform>
|
<uniform>
|
||||||
<name>texture</name>
|
<name>texture</name>
|
||||||
<type>sampler-2d</type>
|
<type>sampler-2d</type>
|
||||||
<value type="int">0</value>
|
<value type="int">0</value>
|
||||||
</uniform>
|
</uniform>
|
||||||
|
<uniform>
|
||||||
|
<name>dataBuffer</name>
|
||||||
|
<type>sampler-1d</type>
|
||||||
|
<value type="int">1</value>
|
||||||
|
</uniform>
|
||||||
<color-mask type="vec4d">0 0 0 0</color-mask>
|
<color-mask type="vec4d">0 0 0 0</color-mask>
|
||||||
</pass>
|
</pass>
|
||||||
<pass>
|
<pass>
|
||||||
|
@ -293,12 +347,39 @@
|
||||||
<use>texture[0]/internal-format</use>
|
<use>texture[0]/internal-format</use>
|
||||||
</internal-format>
|
</internal-format>
|
||||||
</texture-unit>
|
</texture-unit>
|
||||||
|
<texture-unit>
|
||||||
|
<unit>1</unit>
|
||||||
|
<image><use>texture[6]/image</use></image>
|
||||||
|
<type><use>texture[6]/type</use></type>
|
||||||
|
<filter><use>texture[6]/filter</use></filter>
|
||||||
|
<wrap-s><use>texture[6]/wrap-s</use></wrap-s>
|
||||||
|
<wrap-t><use>texture[6]/wrap-t</use></wrap-t>
|
||||||
|
<internal-format>
|
||||||
|
<use>texture[6]/internal-format</use>
|
||||||
|
</internal-format>
|
||||||
|
</texture-unit>
|
||||||
<program>
|
<program>
|
||||||
<vertex-shader>Shaders/building-ALS.vert</vertex-shader>
|
<vertex-shader>Shaders/building-ALS.vert</vertex-shader>
|
||||||
<fragment-shader>Shaders/terrain-ALS-base.frag</fragment-shader>
|
<fragment-shader>Shaders/terrain-ALS-base.frag</fragment-shader>
|
||||||
<fragment-shader>Shaders/hazes.frag</fragment-shader>
|
<fragment-shader>Shaders/hazes.frag</fragment-shader>
|
||||||
<fragment-shader>Shaders/filters-ALS.frag</fragment-shader>
|
<fragment-shader>Shaders/filters-ALS.frag</fragment-shader>
|
||||||
<fragment-shader>Shaders/noise.frag</fragment-shader>
|
<fragment-shader>Shaders/noise.frag</fragment-shader>
|
||||||
|
<attribute>
|
||||||
|
<name>instancePosition</name>
|
||||||
|
<index>10</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>instanceScaleRotate</name>
|
||||||
|
<index>11</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>rotPitchTex0x</name>
|
||||||
|
<index>12</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>tex0yTex1xTex1y</name>
|
||||||
|
<index>13</index>
|
||||||
|
</attribute>
|
||||||
</program>
|
</program>
|
||||||
<uniform>
|
<uniform>
|
||||||
<name>visibility</name>
|
<name>visibility</name>
|
||||||
|
@ -360,6 +441,11 @@
|
||||||
<type>sampler-2d</type>
|
<type>sampler-2d</type>
|
||||||
<value type="int">0</value>
|
<value type="int">0</value>
|
||||||
</uniform>
|
</uniform>
|
||||||
|
<uniform>
|
||||||
|
<name>dataBuffer</name>
|
||||||
|
<type>sampler-1d</type>
|
||||||
|
<value type="int">1</value>
|
||||||
|
</uniform>
|
||||||
<uniform>
|
<uniform>
|
||||||
<name>colorMode</name>
|
<name>colorMode</name>
|
||||||
<type>int</type>
|
<type>int</type>
|
||||||
|
@ -408,6 +494,22 @@
|
||||||
</texture-unit>
|
</texture-unit>
|
||||||
<program n="0">
|
<program n="0">
|
||||||
<vertex-shader n="0">Shaders/building-ubershader.vert</vertex-shader>
|
<vertex-shader n="0">Shaders/building-ubershader.vert</vertex-shader>
|
||||||
|
<attribute>
|
||||||
|
<name>instancePosition</name>
|
||||||
|
<index>10</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>instanceScaleRotate</name>
|
||||||
|
<index>11</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>rotPitchTex0x</name>
|
||||||
|
<index>12</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>tex0yTex1xTex1y</name>
|
||||||
|
<index>13</index>
|
||||||
|
</attribute>
|
||||||
</program>
|
</program>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
@ -448,26 +550,26 @@
|
||||||
</texture-unit>
|
</texture-unit>
|
||||||
<program n="0">
|
<program n="0">
|
||||||
<vertex-shader n="0">Shaders/building-ubershader.vert</vertex-shader>
|
<vertex-shader n="0">Shaders/building-ubershader.vert</vertex-shader>
|
||||||
|
<attribute>
|
||||||
|
<name>instancePosition</name>
|
||||||
|
<index>10</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>instanceScaleRotate</name>
|
||||||
|
<index>11</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>rotPitchTex0x</name>
|
||||||
|
<index>12</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>tex0yTex1xTex1y</name>
|
||||||
|
<index>13</index>
|
||||||
|
</attribute>
|
||||||
</program>
|
</program>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
|
||||||
<technique n="10">
|
|
||||||
<pass>
|
|
||||||
<program n="0">
|
|
||||||
<vertex-shader n="0">Shaders/building-deferred-gbuffer.vert</vertex-shader>
|
|
||||||
</program>
|
|
||||||
</pass>
|
|
||||||
</technique>
|
|
||||||
|
|
||||||
<technique n="11">
|
|
||||||
<pass>
|
|
||||||
<program n="0">
|
|
||||||
<vertex-shader n="0">Shaders/building-default.vert</vertex-shader>
|
|
||||||
</program>
|
|
||||||
</pass>
|
|
||||||
</technique>
|
|
||||||
|
|
||||||
<technique n="12">
|
<technique n="12">
|
||||||
<pass>
|
<pass>
|
||||||
<lighting>true</lighting>
|
<lighting>true</lighting>
|
||||||
|
@ -543,6 +645,17 @@
|
||||||
</internal-format>
|
</internal-format>
|
||||||
-->
|
-->
|
||||||
</texture-unit>
|
</texture-unit>
|
||||||
|
<texture-unit>
|
||||||
|
<unit>1</unit>
|
||||||
|
<image><use>texture[6]/image</use></image>
|
||||||
|
<type><use>texture[6]/type</use></type>
|
||||||
|
<filter><use>texture[6]/filter</use></filter>
|
||||||
|
<wrap-s><use>texture[6]/wrap-s</use></wrap-s>
|
||||||
|
<wrap-t><use>texture[6]/wrap-t</use></wrap-t>
|
||||||
|
<internal-format>
|
||||||
|
<use>texture[6]/internal-format</use>
|
||||||
|
</internal-format>
|
||||||
|
</texture-unit>
|
||||||
<vertex-program-two-side>
|
<vertex-program-two-side>
|
||||||
<use>vertex-program-two-side</use>
|
<use>vertex-program-two-side</use>
|
||||||
</vertex-program-two-side>
|
</vertex-program-two-side>
|
||||||
|
@ -551,6 +664,22 @@
|
||||||
<fragment-shader n="0">Shaders/include_fog.frag</fragment-shader>
|
<fragment-shader n="0">Shaders/include_fog.frag</fragment-shader>
|
||||||
<!--fog include-->
|
<!--fog include-->
|
||||||
<fragment-shader n="1">Shaders/default.frag</fragment-shader>
|
<fragment-shader n="1">Shaders/default.frag</fragment-shader>
|
||||||
|
<attribute>
|
||||||
|
<name>instancePosition</name>
|
||||||
|
<index>10</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>instanceScaleRotate</name>
|
||||||
|
<index>11</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>rotPitchTex0x</name>
|
||||||
|
<index>12</index>
|
||||||
|
</attribute>
|
||||||
|
<attribute>
|
||||||
|
<name>tex0yTex1xTex1y</name>
|
||||||
|
<index>13</index>
|
||||||
|
</attribute>
|
||||||
</program>
|
</program>
|
||||||
<!-- BEGIN fog include -->
|
<!-- BEGIN fog include -->
|
||||||
<!--<uniform>
|
<!--<uniform>
|
||||||
|
@ -601,6 +730,11 @@
|
||||||
<type>sampler-2d</type>
|
<type>sampler-2d</type>
|
||||||
<value type="int">0</value>
|
<value type="int">0</value>
|
||||||
</uniform>
|
</uniform>
|
||||||
|
<uniform>
|
||||||
|
<name>dataBuffer</name>
|
||||||
|
<type>sampler-1d</type>
|
||||||
|
<value type="int">1</value>
|
||||||
|
</uniform>
|
||||||
<uniform>
|
<uniform>
|
||||||
<name>colorMode</name>
|
<name>colorMode</name>
|
||||||
<type>int</type>
|
<type>int</type>
|
||||||
|
|
|
@ -703,16 +703,24 @@ var enable_widgets = func(node, name, enable = 1) {
|
||||||
# GUI theming
|
# GUI theming
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
var nextStyle = func {
|
var nextStyle = func(delta=1) {
|
||||||
var curr = getprop("/sim/gui/current-style");
|
var curr = getprop("/sim/gui/current-style");
|
||||||
var styles = props.globals.getNode("/sim/gui").getChildren("style");
|
var styles = props.globals.getNode("/sim/gui").getChildren("style");
|
||||||
forindex (var i; styles)
|
forindex (var i; styles)
|
||||||
if (styles[i].getIndex() == curr)
|
if (styles[i].getIndex() == curr)
|
||||||
break;
|
break;
|
||||||
if ((i += 1) >= size(styles))
|
i += delta;
|
||||||
|
if (i >= size(styles))
|
||||||
i = 0;
|
i = 0;
|
||||||
|
if (i < 0) {
|
||||||
|
i = size(styles) - 1;
|
||||||
|
}
|
||||||
setprop("/sim/gui/current-style", styles[i].getIndex());
|
setprop("/sim/gui/current-style", styles[i].getIndex());
|
||||||
fgcommand("gui-redraw");
|
fgcommand("gui-redraw");
|
||||||
|
popupTip(sprintf("GUI style %s: %s",
|
||||||
|
styles[i].getIndex(),
|
||||||
|
styles[i].getValue("name"),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -357,8 +357,7 @@ for (var i = 0; i < wsize; i=i+1) {
|
||||||
# gradually fade in the interpolation weight of newly added points to
|
# gradually fade in the interpolation weight of newly added points to
|
||||||
# avoid sudden jumps
|
# avoid sudden jumps
|
||||||
|
|
||||||
if (w.weight < 1.0) {w.weight = w.weight + 0.02;}
|
if (w.weight < 1.0) {w.weight = w.weight + 0.002;}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sum_wind[1] = sum_wind[1] /sum_norm;
|
sum_wind[1] = sum_wind[1] /sum_norm;
|
||||||
|
|
|
@ -183,27 +183,34 @@ var dialog = {
|
||||||
me.toggle_unit(); # set to imperial
|
me.toggle_unit(); # set to imperial
|
||||||
#
|
#
|
||||||
# "private"
|
# "private"
|
||||||
me.font = { name: getprop("/sim/gui/selected-style/fonts/mp-list/name") or "FIXED_8x13",
|
me.font = { name: getprop("/sim/gui/selected-style/fonts/mp-list/name"),
|
||||||
size: getprop("/sim/gui/selected-style/fonts/mp-list/size") or 20,
|
size: getprop("/sim/gui/selected-style/fonts/mp-list/size"),
|
||||||
slant: getprop("/sim/gui/selected-style/fonts/mp-list/slant") or 0,
|
slant: getprop("/sim/gui/selected-style/fonts/mp-list/slant"),
|
||||||
};
|
};
|
||||||
|
#printf('me.font is: %s', view.str(me.font));
|
||||||
|
if (me.font.name == nil) {
|
||||||
|
# We try to cope if no font is specified, so that we inherit
|
||||||
|
# whatever default there is.
|
||||||
|
printf("Failed to find font for Pilot List dialog");
|
||||||
|
me.font = nil;
|
||||||
|
}
|
||||||
|
|
||||||
me.header = ["view", " callsign", " model", func dialog.dist_hdr, func dialog.alt_hdr ~ " ", "", " brg", "chat", "ignore" ~ " ", " code", "ver", "airport", " set"];
|
me.header = ["view", " callsign", " model", func dialog.dist_hdr, func dialog.alt_hdr ~ " ", "", " brg", "chat", "ignore" ~ " ", " code", "ver", "airport", " set"];
|
||||||
me.columns = [
|
me.columns = [
|
||||||
{ type: "checkbox", legend: "", property: "view", halign: "right", "pref-height": 14, "pref-width": 14, callback: "multiplayer.view_select", argprop: "callsign", },
|
{ type: "checkbox", legend: "", property: "view", halign: "right", "pref-height": 14, "pref-width": 14, callback: "multiplayer.view_select", argprop: "callsign", },
|
||||||
{ type: "text", property: "callsign", format: " %s", label: "-----------", halign: "fill" , font: me.font },
|
{ type: "text", property: "callsign", format: " %s", label: "-----------", halign: "fill" },
|
||||||
{ type: "text", property: "model-short", format: " %s", label: "--------------", halign: "fill" , font: me.font },
|
{ type: "text", property: "model-short", format: " %s", label: "--------------", halign: "fill" },
|
||||||
{ type: "text", property: func dialog.dist_node, format:" %8.2f", label: "---------", halign: "right", font: me.font },
|
{ type: "text", property: func dialog.dist_node, format:" %8.2f", label: "---------", halign: "right" },
|
||||||
{ type: "text", property: func dialog.alt_node, format:" %7.0f", label: "---------", halign: "right", font: me.font },
|
{ type: "text", property: func dialog.alt_node, format:" %7.0f", label: "---------", halign: "right" },
|
||||||
{ type: "text", property: "ascent_descent", format: "%s", label: "-", halign: "right", font: me.font },
|
{ type: "text", property: "ascent_descent", format: "%s", label: "-", halign: "right" },
|
||||||
{ type: "text", property: "bearing-to", format: " %3.0f", label: "----", halign: "right", font: me.font },
|
{ type: "text", property: "bearing-to", format: " %3.0f", label: "----", halign: "right" },
|
||||||
{ type: "button", legend: "", halign: "right", callback: "multiplayer.compose_message", "pref-height": 14, "pref-width": 14 },
|
{ type: "button", legend: "", halign: "right", callback: "multiplayer.compose_message", "pref-height": 14, "pref-width": 14 },
|
||||||
{ type: "checkbox", property: "controls/invisible", callback: "multiplayer.dialog.toggle_ignore",
|
{ type: "checkbox", property: "controls/invisible", callback: "multiplayer.dialog.toggle_ignore",
|
||||||
argprop: "callsign", label: "---------", halign: "right", font: me.font },
|
argprop: "callsign", label: "---------", halign: "right" },
|
||||||
{ type: "text", property: "id-code", format: " %s", label: "-", halign: "fill" , font: me.font },
|
{ type: "text", property: "id-code", format: " %s", label: "-", halign: "fill" },
|
||||||
{ type: "text", property: "sim/multiplay/protocol-version", format: " %s", label: "--", halign: "fill" , font: me.font },
|
{ type: "text", property: "sim/multiplay/protocol-version", format: " %s", label: "--", halign: "fill" },
|
||||||
{ type: "text", property: "airport-id", format: "%s", label: "----", halign: "fill" , font: me.font },
|
{ type: "text", property: "airport-id", format: "%s", label: "----", halign: "fill" },
|
||||||
{ type: "text", property: "set-loaded", format: "%s", label: "----", halign: "fill" , font: me.font },
|
{ type: "text", property: "set-loaded", format: "%s", label: "----", halign: "fill" },
|
||||||
];
|
];
|
||||||
me.cs_warnings = {};
|
me.cs_warnings = {};
|
||||||
me.name = "who-is-online";
|
me.name = "who-is-online";
|
||||||
|
@ -224,7 +231,9 @@ var dialog = {
|
||||||
me.dialog = gui.dialog[me.name] = gui.Widget.new();
|
me.dialog = gui.dialog[me.name] = gui.Widget.new();
|
||||||
me.dialog.set("name", me.name);
|
me.dialog.set("name", me.name);
|
||||||
me.dialog.set("dialog-name", me.name);
|
me.dialog.set("dialog-name", me.name);
|
||||||
me.dialog.set("font", me.font.name);
|
if (typeof(me.font) == 'hash' and contains(me.font, "name") and me.font.name != nil) {
|
||||||
|
me.dialog.set("font", me.font.name);
|
||||||
|
}
|
||||||
if (me.x != nil)
|
if (me.x != nil)
|
||||||
me.dialog.set("x", me.x);
|
me.dialog.set("x", me.x);
|
||||||
if (me.y != nil)
|
if (me.y != nil)
|
||||||
|
@ -235,6 +244,15 @@ var dialog = {
|
||||||
|
|
||||||
me.dialog.setColor(me.bg[0], me.bg[1], me.bg[2], me.bg[3]);
|
me.dialog.setColor(me.bg[0], me.bg[1], me.bg[2], me.bg[3]);
|
||||||
|
|
||||||
|
# Sets out default foreground colour and also me.font if it is not nil.
|
||||||
|
#
|
||||||
|
set_default = func(w) {
|
||||||
|
w.setColor(me.fg[1][0], me.fg[1][1], me.fg[1][2], me.fg[1][3],);
|
||||||
|
if (me.font != nil) {
|
||||||
|
w.node.setValues({ "font": me.font});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var titlebar = me.dialog.addChild("group");
|
var titlebar = me.dialog.addChild("group");
|
||||||
titlebar.set("layout", "hbox");
|
titlebar.set("layout", "hbox");
|
||||||
|
|
||||||
|
@ -249,10 +267,13 @@ var dialog = {
|
||||||
w.setBinding("nasal", "multiplayer.dialog.toggle_unit(); multiplayer.dialog._redraw_()");
|
w.setBinding("nasal", "multiplayer.dialog.toggle_unit(); multiplayer.dialog._redraw_()");
|
||||||
|
|
||||||
titlebar.addChild("empty").set("stretch", 1);
|
titlebar.addChild("empty").set("stretch", 1);
|
||||||
titlebar.addChild("text").set("label", "Pilots: ");
|
var w = titlebar.addChild("text");
|
||||||
|
w.set("label", "Pilots: ");
|
||||||
|
set_default(w);
|
||||||
|
|
||||||
var p = titlebar.addChild("text");
|
var w = titlebar.addChild("text");
|
||||||
p.node.setValues({ label: "---", live: 1, format: "%d", property: "ai/models/num-players" });
|
set_default(w);
|
||||||
|
w.node.setValues({ label: "---", live: 1, format: "%d", property: "ai/models/num-players" });
|
||||||
titlebar.addChild("empty").set("stretch", 1);
|
titlebar.addChild("empty").set("stretch", 1);
|
||||||
|
|
||||||
var w = titlebar.addChild("button");
|
var w = titlebar.addChild("button");
|
||||||
|
@ -271,10 +292,9 @@ var dialog = {
|
||||||
var col = 0;
|
var col = 0;
|
||||||
foreach (var h; me.header) {
|
foreach (var h; me.header) {
|
||||||
var w = content.addChild("text");
|
var w = content.addChild("text");
|
||||||
w.node.setValues({ "font" : me.font});
|
|
||||||
|
|
||||||
var l = typeof(h) == "func" ? h() : h;
|
var l = typeof(h) == "func" ? h() : h;
|
||||||
w.node.setValues({ "label": l, "row": row, "col": col, halign: me.columns[col].halign });
|
w.node.setValues({ "label": l, "row": row, "col": col, halign: me.columns[col].halign });
|
||||||
|
set_default(w);
|
||||||
w = content.addChild("hrule");
|
w = content.addChild("hrule");
|
||||||
w.node.setValues({ "row": row + 1, "col": col });
|
w.node.setValues({ "row": row + 1, "col": col });
|
||||||
col += 1;
|
col += 1;
|
||||||
|
@ -289,21 +309,22 @@ var dialog = {
|
||||||
color = me.fg[1];
|
color = me.fg[1];
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
print("no model installed; check fallback");
|
#print("no model installed; check fallback");
|
||||||
var fbn = mp.node.getNode("sim/model/fallback-model-index");
|
var fbn = mp.node.getNode("sim/model/fallback-model-index");
|
||||||
if (fbn != nil){
|
if (fbn != nil){
|
||||||
print(" ->> got fallback node =",fbn.getValue());
|
#print(" ->> got fallback node =",fbn.getValue());
|
||||||
if (fbn.getValue() > 0) {
|
if (fbn.getValue() > 0) {
|
||||||
color = me.fg[3];
|
color = me.fg[3];
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
print(" ->> no fallback node");
|
#print(" ->> no fallback node");
|
||||||
}
|
}
|
||||||
foreach (var column; me.columns) {
|
foreach (var column; me.columns) {
|
||||||
var w = nil;
|
var w = nil;
|
||||||
if (column.type == "button") {
|
if (column.type == "button") {
|
||||||
w = content.addChild("button");
|
w = content.addChild("button");
|
||||||
w.node.setValues(column);
|
w.node.setValues(column);
|
||||||
|
set_default(w);
|
||||||
w.setBinding("nasal", column.callback ~ "(\"" ~ mp.callsign ~ "\",);");
|
w.setBinding("nasal", column.callback ~ "(\"" ~ mp.callsign ~ "\",);");
|
||||||
w.node.setValues({ row: row, col: col});
|
w.node.setValues({ row: row, col: col});
|
||||||
} else {
|
} else {
|
||||||
|
@ -311,9 +332,11 @@ var dialog = {
|
||||||
if (column.type == "text") {
|
if (column.type == "text") {
|
||||||
w = content.addChild("text");
|
w = content.addChild("text");
|
||||||
w.node.setValues(column);
|
w.node.setValues(column);
|
||||||
|
set_default(w);
|
||||||
} elsif (column.type == "checkbox") {
|
} elsif (column.type == "checkbox") {
|
||||||
w = content.addChild("checkbox");
|
w = content.addChild("checkbox");
|
||||||
w.setBinding("nasal", column.callback ~ "(getprop(\"" ~ mp.root ~ "/" ~ column.argprop ~ "\"))");
|
w.setBinding("nasal", column.callback ~ "(getprop(\"" ~ mp.root ~ "/" ~ column.argprop ~ "\"))");
|
||||||
|
set_default(w);
|
||||||
}
|
}
|
||||||
w.node.setValues({ row: row, col: col, live: 1, property: mp.root ~ "/" ~ p });
|
w.node.setValues({ row: row, col: col, live: 1, property: mp.root ~ "/" ~ p });
|
||||||
}
|
}
|
||||||
|
|
154
Nasal/view.nas
|
@ -5,7 +5,9 @@
|
||||||
|
|
||||||
# ATTENTION:
|
# ATTENTION:
|
||||||
# /sim/current-view/view-number is in the range 0..viewCount, it is NOT
|
# /sim/current-view/view-number is in the range 0..viewCount, it is NOT
|
||||||
# the index used in aircraft XML files (e.g. <view n="100">)
|
# the index used in aircraft XML files (e.g. <view n="100">).
|
||||||
|
#
|
||||||
|
# For the latter, use /sim/current-view/view-number-raw.
|
||||||
|
|
||||||
# For debugging. Returns string containing description of <x>.
|
# For debugging. Returns string containing description of <x>.
|
||||||
#
|
#
|
||||||
|
@ -258,9 +260,9 @@ var manager = {
|
||||||
forindex (var i; viewnodes) {
|
forindex (var i; viewnodes) {
|
||||||
# Install this view, marking as multiplayer if appropriate.
|
# Install this view, marking as multiplayer if appropriate.
|
||||||
var multiplayer = 1;
|
var multiplayer = 1;
|
||||||
if (i==4 or i==6) {
|
if (0) {
|
||||||
# Fly-by and Tower Look From views do not currently
|
# Use this for views that do not work with multiplayer
|
||||||
# support multiplayer aircraft.
|
# aircraft.
|
||||||
multiplayer = 0;
|
multiplayer = 0;
|
||||||
}
|
}
|
||||||
var viewnode = viewnodes[i];
|
var viewnode = viewnodes[i];
|
||||||
|
@ -359,39 +361,105 @@ var manager = {
|
||||||
|
|
||||||
|
|
||||||
var fly_by_view_handler = {
|
var fly_by_view_handler = {
|
||||||
init : func {
|
|
||||||
me.latN = props.globals.getNode("/sim/viewer/latitude-deg", 1);
|
|
||||||
me.lonN = props.globals.getNode("/sim/viewer/longitude-deg", 1);
|
|
||||||
me.altN = props.globals.getNode("/sim/viewer/altitude-ft", 1);
|
|
||||||
me.vnN = props.globals.getNode("/velocities/speed-north-fps", 1);
|
|
||||||
me.veN = props.globals.getNode("/velocities/speed-east-fps", 1);
|
|
||||||
me.hdgN = props.globals.getNode("/orientation/heading-deg", 1);
|
|
||||||
|
|
||||||
|
init : func {
|
||||||
setlistener("/sim/signals/reinit", func(n) { n.getValue() or me.reset() });
|
setlistener("/sim/signals/reinit", func(n) { n.getValue() or me.reset() });
|
||||||
setlistener("/sim/crashed", func(n) { n.getValue() and me.reset() });
|
setlistener("/sim/crashed", func(n) { n.getValue() and me.reset() });
|
||||||
setlistener("/sim/freeze/replay-state", func {
|
setlistener("/sim/freeze/replay-state", func {
|
||||||
settimer(func { me.reset() }, 1); # time for replay to catch up
|
settimer(func { me.reset() }, 1); # time for replay to catch up
|
||||||
});
|
});
|
||||||
me.reset();
|
setlistener("/sim/current-view/multiplayer", func(n) { me.reset(); } );
|
||||||
|
|
||||||
|
me.reset();
|
||||||
},
|
},
|
||||||
|
|
||||||
start : func {
|
start : func {
|
||||||
me.reset();
|
me.reset();
|
||||||
},
|
},
|
||||||
reset: func {
|
|
||||||
me.chase = -getprop("/sim/chase-distance-m");
|
|
||||||
# me.course = me.hdgN.getValue();
|
|
||||||
var vn = me.vnN.getValue();
|
|
||||||
var ve = me.veN.getValue();
|
|
||||||
me.course = (0.5*math.pi - math.atan2(vn, ve))*R2D;
|
|
||||||
|
|
||||||
me.last = geo.aircraft_position();
|
# Sets me.root to node with path given by the value of property
|
||||||
|
# /sim/view[6]/config/root (which will be /ai/models/multiplayer[N]
|
||||||
|
# where N is the index of the multiplayer aircraft]. Note that this
|
||||||
|
# node sometimes doesn't yet exist, in which case we return with
|
||||||
|
# me.root = nil.
|
||||||
|
#
|
||||||
|
_set_multiplayer_root: func() {
|
||||||
|
# Set me.root to /ai/models/multiplayer[.]
|
||||||
|
var root = getprop("/sim/view[6]/config/root"); # /ai/models/multiplayer[]
|
||||||
|
me.root = props.globals.getNode(root);
|
||||||
|
if (me.root == nil) {
|
||||||
|
#printf("root does not exist: %s", str(root));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
aircraft_position: func() {
|
||||||
|
if (me.multiplayer) {
|
||||||
|
me._set_multiplayer_root();
|
||||||
|
if (me.root == nil) {
|
||||||
|
return geo.Coord.new();
|
||||||
|
}
|
||||||
|
var lat = me.root.getValue("position/latitude-deg");
|
||||||
|
var lon = me.root.getValue("position/longitude-deg");
|
||||||
|
var alt = me.root.getValue("position/altitude-ft") * FT2M;
|
||||||
|
|
||||||
|
return geo.Coord.new().set_latlon(lat, lon, alt);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return geo.aircraft_position();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
reset: func {
|
||||||
|
me.multiplayer = getprop("/sim/current-view/multiplayer") or 0;
|
||||||
|
|
||||||
|
if (me.multiplayer) {
|
||||||
|
me._set_multiplayer_root();
|
||||||
|
if (me.root == nil) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
me.chase = me.root.getValue("set/sim/chase-distance-m");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
me.chase = getprop("/sim/chase-distance-m");
|
||||||
|
}
|
||||||
|
if (me.chase == nil or me.chase == 0) me.chase = -25;
|
||||||
|
me.chase = -me.chase;
|
||||||
|
|
||||||
|
me.last = me.aircraft_position();
|
||||||
me.setpos(1);
|
me.setpos(1);
|
||||||
# me.dist = 20;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setpos : func(force = 0) {
|
setpos : func(force = 0) {
|
||||||
var pos = geo.aircraft_position();
|
if (me.multiplayer) {
|
||||||
var vn = me.vnN.getValue();
|
me._set_multiplayer_root();
|
||||||
var ve = me.veN.getValue();
|
if (me.root == nil) {
|
||||||
|
return 1; # Ensure we get called back soon to try again.
|
||||||
|
}
|
||||||
|
# We would like to find the aircraft's actual velocity
|
||||||
|
# vector rather than heading, but it's not easily available
|
||||||
|
# as a property, so we use the aircraft heading and its
|
||||||
|
# forwards speed (uBody-fps).
|
||||||
|
#
|
||||||
|
# E.g. i think this may give biased viewpoint positions if
|
||||||
|
# aircraft is moving sideways due to wind.
|
||||||
|
#
|
||||||
|
var u = me.root.getValue("velocities/uBody-fps"); # forwards
|
||||||
|
#var v = me.root.getValue("velocities/vBody-fps"); # vertical
|
||||||
|
#var w = me.root.getValue("velocities/wBody-fps"); # lateral
|
||||||
|
|
||||||
|
var course = me.root.getValue("orientation/true-heading-deg");
|
||||||
|
var course_rad = course * math.pi / 180;
|
||||||
|
var vn = u * math.cos(course_rad);
|
||||||
|
var ve = u * -math.sin(course_rad);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var vn = getprop("/velocities/speed-north-fps");
|
||||||
|
var ve = getprop("/velocities/speed-east-fps");
|
||||||
|
var course = (0.5*math.pi - math.atan2(vn, ve))*R2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pos = me.aircraft_position();
|
||||||
|
|
||||||
var dist = 0.0;
|
var dist = 0.0;
|
||||||
if ( force ) {
|
if ( force ) {
|
||||||
|
@ -409,17 +477,25 @@ var fly_by_view_handler = {
|
||||||
if (dist < 1.7 * me.chase and !force)
|
if (dist < 1.7 * me.chase and !force)
|
||||||
return 1.13;
|
return 1.13;
|
||||||
|
|
||||||
# "predict" and remember next aircraft position
|
# "predict" and remember next aircraft position
|
||||||
# var course = me.hdgN.getValue();
|
var delta_alt = (pos.alt() - me.last.alt()) * 0.5;
|
||||||
var course = (0.5*math.pi - math.atan2(vn, ve))*R2D;
|
|
||||||
var delta_alt = (pos.alt() - me.last.alt()) * 0.5;
|
|
||||||
pos.apply_course_distance(course, dist * 0.8);
|
pos.apply_course_distance(course, dist * 0.8);
|
||||||
pos.set_alt(pos.alt() + delta_alt);
|
pos.set_alt(pos.alt() + delta_alt);
|
||||||
me.last.set(pos);
|
me.last.set(pos);
|
||||||
|
|
||||||
# apply random deviation
|
# apply random deviation
|
||||||
var radius = me.chase * (0.5 * rand() + 0.7);
|
var radius = me.chase * (0.5 * rand() + 0.7);
|
||||||
var agl = getprop("/position/altitude-agl-ft") * FT2M;
|
|
||||||
|
if (me.multiplayer) {
|
||||||
|
# AGL not available for multiplayer aircraft as a property,
|
||||||
|
# so we calculate it explicitly.
|
||||||
|
var gl = geo.elevation(pos.lat(), pos.lon());
|
||||||
|
if (gl == nil) gl = 0;
|
||||||
|
var agl = pos.alt() - gl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var agl = getprop("/position/altitude-agl-ft") * FT2M;
|
||||||
|
}
|
||||||
if (agl > me.chase)
|
if (agl > me.chase)
|
||||||
var angle = rand() * 2 * math.pi;
|
var angle = rand() * 2 * math.pi;
|
||||||
else
|
else
|
||||||
|
@ -429,7 +505,7 @@ var fly_by_view_handler = {
|
||||||
var dev_side = math.sin(angle) * radius;
|
var dev_side = math.sin(angle) * radius;
|
||||||
pos.apply_course_distance(course + 90, dev_side);
|
pos.apply_course_distance(course + 90, dev_side);
|
||||||
|
|
||||||
# and make sure it's not under ground
|
# and make sure it's not under ground
|
||||||
var lat = pos.lat();
|
var lat = pos.lat();
|
||||||
var lon = pos.lon();
|
var lon = pos.lon();
|
||||||
var alt = pos.alt();
|
var alt = pos.alt();
|
||||||
|
@ -445,11 +521,23 @@ var fly_by_view_handler = {
|
||||||
}
|
}
|
||||||
|
|
||||||
# set new view point
|
# set new view point
|
||||||
me.latN.setValue(lat);
|
if (me.multiplayer) {
|
||||||
me.lonN.setValue(lon);
|
# flightgear:src/Viewer/view.cxx will
|
||||||
me.altN.setValue(alt * M2FT);
|
# expect to find viewing position in
|
||||||
|
# /ai/models/multiplayer[]/sim/viewer/latitude-deg etc.
|
||||||
|
#
|
||||||
|
me.root.setValue("sim/viewer/latitude-deg", lat);
|
||||||
|
me.root.setValue("sim/viewer/longitude-deg", lon);
|
||||||
|
me.root.setValue("sim/viewer/altitude-ft", alt * M2FT);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setprop("/sim/viewer/latitude-deg", lat);
|
||||||
|
setprop("/sim/viewer/longitude-deg", lon);
|
||||||
|
setprop("/sim/viewer/altitude-ft", alt * M2FT);
|
||||||
|
}
|
||||||
return 7.3;
|
return 7.3;
|
||||||
},
|
},
|
||||||
|
|
||||||
update : func {
|
update : func {
|
||||||
return me.setpos();
|
return me.setpos();
|
||||||
},
|
},
|
||||||
|
@ -530,8 +618,10 @@ var model_view_handler_class = {
|
||||||
setup: func(data) {
|
setup: func(data) {
|
||||||
if (data.root == '/') {
|
if (data.root == '/') {
|
||||||
var ident = '[' ~ data.callsign ~ ']';
|
var ident = '[' ~ data.callsign ~ ']';
|
||||||
|
setprop('/sim/current-view/multiplayer', 0);
|
||||||
} else {
|
} else {
|
||||||
var ident = '"' ~ data.callsign ~ '" (' ~ data.model ~ ')';
|
var ident = '"' ~ data.callsign ~ '" (' ~ data.model ~ ')';
|
||||||
|
setprop('/sim/current-view/multiplayer', 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
me.current = data.callsign;
|
me.current = data.callsign;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// -*-C++-*-
|
// -*-C++-*-
|
||||||
#version 120
|
#version 120
|
||||||
|
#extension GL_EXT_draw_instanced : enable
|
||||||
|
|
||||||
// Shader that uses OpenGL state values to do per-pixel lighting
|
// Shader that uses OpenGL state values to do per-pixel lighting
|
||||||
//
|
//
|
||||||
|
@ -15,6 +16,11 @@
|
||||||
#define MODE_DIFFUSE 1
|
#define MODE_DIFFUSE 1
|
||||||
#define MODE_AMBIENT_AND_DIFFUSE 2
|
#define MODE_AMBIENT_AND_DIFFUSE 2
|
||||||
|
|
||||||
|
attribute vec3 instancePosition; // (x,y,z)
|
||||||
|
attribute vec3 instanceScaleRotate; // (width, depth, height)
|
||||||
|
attribute vec3 rotPitchTex0x; // (rotation, pitch height, texture x offset)
|
||||||
|
attribute vec3 tex0yTex1xTex1y; // (texture y offset, texture x gain, texture y gain)
|
||||||
|
|
||||||
// The constant term of the lighting equation that doesn't depend on
|
// The constant term of the lighting equation that doesn't depend on
|
||||||
// the surface normal is passed in gl_{Front,Back}Color. The alpha
|
// the surface normal is passed in gl_{Front,Back}Color. The alpha
|
||||||
// component is set to 1 for front, 0 for back in order to work around
|
// component is set to 1 for front, 0 for back in order to work around
|
||||||
|
@ -74,26 +80,45 @@ void main()
|
||||||
float scattering;
|
float scattering;
|
||||||
vec3 shadedFogColor = vec3(0.55, 0.67, 0.88);
|
vec3 shadedFogColor = vec3(0.55, 0.67, 0.88);
|
||||||
|
|
||||||
// this code is copied from default.vert
|
// Determine the rotation for the building.
|
||||||
|
float sr = sin(6.28 * rotPitchTex0x.x);
|
||||||
|
float cr = cos(6.28 * rotPitchTex0x.x);
|
||||||
|
|
||||||
//vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
|
// Adjust pitch of roof to the correct height.
|
||||||
// Determine the rotation for the building. The Color alpha value provides rotation information
|
// The top roof vertices are the only ones that have fractional z values (1.5),
|
||||||
float sr = sin(6.28 * gl_Color.a);
|
// so we can use this to identify them and scale up any pitched roof vertex to
|
||||||
float cr = cos(6.28 * gl_Color.a);
|
// the correct pitch (rotPitchTex0x.y * 2.0 because of the fractional z value),
|
||||||
|
// then scale down by the building height (instanceScaleRotate.z) because
|
||||||
|
// immediately afterwards we will scale UP the vertex to the correct scale.
|
||||||
|
vec3 position = gl_Vertex.xyz;
|
||||||
|
position.z = position.z + fract(position.z) * 2.0 * rotPitchTex0x.y / instanceScaleRotate.z - fract(position.z);
|
||||||
|
position = position * instanceScaleRotate.xyz;
|
||||||
|
|
||||||
vec3 position = gl_Vertex.xyz;
|
// Rotation of the building and movement into position
|
||||||
|
position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr)));
|
||||||
|
position = position + instancePosition.xyz;
|
||||||
|
|
||||||
// Rotation of the building and movement into position
|
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
|
||||||
position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr)));
|
|
||||||
position = position + gl_Color.xyz;
|
|
||||||
|
|
||||||
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
|
// Texture coordinates are stored as tex0 and tex1 across two attributes.
|
||||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
// tex0 contains the bottom leftmost point, and tex1 contains (w,h).
|
||||||
|
gl_TexCoord[0].x = sign(gl_MultiTexCoord0.x) * rotPitchTex0x.z + gl_MultiTexCoord0.x * tex0yTex1xTex1y.y;
|
||||||
|
gl_TexCoord[0].y = tex0yTex1xTex1y.x + gl_MultiTexCoord0.y * tex0yTex1xTex1y.z;
|
||||||
|
|
||||||
|
// Rotate the normal.
|
||||||
|
normal = gl_Normal;
|
||||||
|
|
||||||
|
// The roof pieces have a normal of (+/-0.7, 0.0, 0.7)
|
||||||
|
// If the roof is flat, then we need to change it to (0,0,1).
|
||||||
|
// First term evaluates for normals without a +z component (all except roof)
|
||||||
|
// Second term evaluates for roof normals with a pitch
|
||||||
|
// Third term evaluates for flat roofs
|
||||||
|
normal = step(0.5, 1.0 - normal.z) * normal + step(0.5, normal.z) * clamp(rotPitchTex0x.y, 0.0, 1.0) * normal + step(0.5, normal.z) * (1.0 - clamp(rotPitchTex0x.y, 0.0, 1.0)) * vec3(0,0,1);
|
||||||
|
|
||||||
|
// Rotate the normal as per the building.
|
||||||
|
normal.xy = vec2(dot(normal.xy, vec2(cr, sr)), dot(normal.xy, vec2(-sr, cr)));
|
||||||
|
normal = gl_NormalMatrix * normal;
|
||||||
|
|
||||||
// Rotate the normal.
|
|
||||||
normal = gl_Normal;
|
|
||||||
normal.xy = vec2(dot(normal.xy, vec2(cr, sr)), dot(normal.xy, vec2(-sr, cr)));
|
|
||||||
normal = gl_NormalMatrix * normal;
|
|
||||||
|
|
||||||
vec4 ambient_color, diffuse_color;
|
vec4 ambient_color, diffuse_color;
|
||||||
if (colorMode == MODE_DIFFUSE) {
|
if (colorMode == MODE_DIFFUSE) {
|
||||||
|
@ -254,4 +279,3 @@ if (use_IR_vision)
|
||||||
gl_BackColor.rgb = constant_term.rgb;
|
gl_BackColor.rgb = constant_term.rgb;
|
||||||
//gl_FrontColor.a = mie_angle; gl_BackColor.a = mie_angle;
|
//gl_FrontColor.a = mie_angle; gl_BackColor.a = mie_angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,16 @@
|
||||||
// Diffuse colors come from the gl_Color, ambient from the material. This is
|
// Diffuse colors come from the gl_Color, ambient from the material. This is
|
||||||
// equivalent to osg::Material::DIFFUSE.
|
// equivalent to osg::Material::DIFFUSE.
|
||||||
#version 120
|
#version 120
|
||||||
|
#extension GL_EXT_draw_instanced : enable
|
||||||
#define MODE_OFF 0
|
#define MODE_OFF 0
|
||||||
#define MODE_DIFFUSE 1
|
#define MODE_DIFFUSE 1
|
||||||
#define MODE_AMBIENT_AND_DIFFUSE 2
|
#define MODE_AMBIENT_AND_DIFFUSE 2
|
||||||
|
|
||||||
|
attribute vec3 instancePosition; // (x,y,z)
|
||||||
|
attribute vec3 instanceScaleRotate; // (width, depth, height)
|
||||||
|
attribute vec3 rotPitchTex0x; // (rotation, pitch height, texture x offset)
|
||||||
|
attribute vec3 tex0yTex1xTex1y; // (texture y offset, texture x gain, texture y gain)
|
||||||
|
|
||||||
// The constant term of the lighting equation that doesn't depend on
|
// The constant term of the lighting equation that doesn't depend on
|
||||||
// the surface normal is passed in gl_{Front,Back}Color. The alpha
|
// the surface normal is passed in gl_{Front,Back}Color. The alpha
|
||||||
// component is set to 1 for front, 0 for back in order to work around
|
// component is set to 1 for front, 0 for back in order to work around
|
||||||
|
@ -29,24 +35,42 @@ uniform int colorMode;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
// Determine the rotation for the building.
|
||||||
|
float sr = sin(6.28 * rotPitchTex0x.x);
|
||||||
|
float cr = cos(6.28 * rotPitchTex0x.x);
|
||||||
|
|
||||||
// Determine the rotation for the building. The Color alpha value provides rotation information
|
// Adjust pitch of roof to the correct height.
|
||||||
float sr = sin(6.28 * gl_Color.a);
|
// The top roof vertices are the only ones that have fractional z values (1.5),
|
||||||
float cr = cos(6.28 * gl_Color.a);
|
// so we can use this to identify them and scale up any pitched roof vertex to
|
||||||
|
// the correct pitch (rotPitchTex0x.y * 2.0 because of the fractional z value),
|
||||||
|
// then scale down by the building height (instanceScaleRotate.z) because
|
||||||
|
// immediately afterwards we will scale UP the vertex to the correct scale.
|
||||||
vec3 position = gl_Vertex.xyz;
|
vec3 position = gl_Vertex.xyz;
|
||||||
|
position.z = position.z + fract(position.z) * 2.0 * rotPitchTex0x.y / instanceScaleRotate.z - fract(position.z);
|
||||||
|
position = position * instanceScaleRotate.xyz;
|
||||||
|
|
||||||
// Rotation of the building and movement into position
|
// Rotation of the building and movement into position
|
||||||
position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr)));
|
position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr)));
|
||||||
position = position + gl_Color.xyz;
|
position = position + instancePosition.xyz;
|
||||||
|
|
||||||
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
|
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
|
||||||
|
|
||||||
//gl_Position = ftransform();
|
// Texture coordinates are stored as tex0 and tex1 across two attributes.
|
||||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
// tex0 contains the bottom leftmost point, and tex1 contains (w,h).
|
||||||
|
gl_TexCoord[0].x = sign(gl_MultiTexCoord0.x) * rotPitchTex0x.z + gl_MultiTexCoord0.x * tex0yTex1xTex1y.y;
|
||||||
|
gl_TexCoord[0].y = tex0yTex1xTex1y.x + gl_MultiTexCoord0.y * tex0yTex1xTex1y.z;
|
||||||
|
|
||||||
// Rotate the normal.
|
// Rotate the normal.
|
||||||
normal = gl_Normal;
|
normal = gl_Normal;
|
||||||
|
|
||||||
|
// The roof pieces have a normal of (+/-0.7, 0.0, 0.7)
|
||||||
|
// If the roof is flat, then we need to change it to (0,0,1).
|
||||||
|
// First term evaluates for normals without a +z component (all except roof)
|
||||||
|
// Second term evaluates for roof normals with a pitch
|
||||||
|
// Third term evaluates for flat roofs
|
||||||
|
normal = step(0.5, 1.0 - normal.z) * normal + step(0.5, normal.z) * clamp(rotPitchTex0x.y, 0.0, 1.0) * normal + step(0.5, normal.z) * (1.0 - clamp(rotPitchTex0x.y, 0.0, 1.0)) * vec3(0,0,1);
|
||||||
|
|
||||||
|
// Rotate the normal as per the building.
|
||||||
normal.xy = vec2(dot(normal.xy, vec2(cr, sr)), dot(normal.xy, vec2(-sr, cr)));
|
normal.xy = vec2(dot(normal.xy, vec2(cr, sr)), dot(normal.xy, vec2(-sr, cr)));
|
||||||
normal = gl_NormalMatrix * normal;
|
normal = gl_NormalMatrix * normal;
|
||||||
|
|
||||||
|
|
|
@ -3,29 +3,60 @@
|
||||||
// Author: Frederic Bouvier.
|
// Author: Frederic Bouvier.
|
||||||
//
|
//
|
||||||
#version 120
|
#version 120
|
||||||
|
#extension GL_EXT_draw_instanced : enable
|
||||||
|
|
||||||
|
attribute vec3 instancePosition; // (x,y,z)
|
||||||
|
attribute vec3 instanceScaleRotate; // (width, depth, height)
|
||||||
|
attribute vec3 rotPitchTex0x; // (rotation, pitch height, texture x offset)
|
||||||
|
attribute vec3 tex0yTex1xTex1y; // (texture y offset, texture x gain, texture y gain)
|
||||||
|
|
||||||
varying vec3 ecNormal;
|
varying vec3 ecNormal;
|
||||||
varying float alpha;
|
varying float alpha;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// Determine the rotation for the building. The Color alpha value provides rotation information
|
// Determine the rotation for the building.
|
||||||
float sr = sin(6.28 * gl_Color.a);
|
float sr = sin(6.28 * rotPitchTex0x.x);
|
||||||
float cr = cos(6.28 * gl_Color.a);
|
float cr = cos(6.28 * rotPitchTex0x.x);
|
||||||
|
|
||||||
vec3 position = gl_Vertex.xyz;
|
// Adjust pitch of roof to the correct height.
|
||||||
|
// The top roof vertices are the only ones that have fractional z values (1.5),
|
||||||
|
// so we can use this to identify them and scale up any pitched roof vertex to
|
||||||
|
// the correct pitch (rotPitchTex0x.y * 2.0 because of the fractional z value),
|
||||||
|
// then scale down by the building height (instanceScaleRotate.z) because
|
||||||
|
// immediately afterwards we will scale UP the vertex to the correct scale.
|
||||||
|
vec3 position = gl_Vertex.xyz;
|
||||||
|
position.z = position.z + fract(position.z) * 2.0 * rotPitchTex0x.y / instanceScaleRotate.z - fract(position.z);
|
||||||
|
position = position * instanceScaleRotate.xyz;
|
||||||
|
|
||||||
// Rotation of the building and movement into position
|
// Rotation of the building and movement into position
|
||||||
position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr)));
|
position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr)));
|
||||||
position = position + gl_Color.xyz;
|
position = position + instancePosition.xyz;
|
||||||
|
|
||||||
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
|
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
|
||||||
|
|
||||||
// Rotate the normal.
|
// Texture coordinates are stored as tex0 and tex1 across two attributes.
|
||||||
ecNormal = gl_Normal;
|
// tex0 contains the bottom leftmost point, and tex1 contains (w,h).
|
||||||
ecNormal.xy = vec2(dot(ecNormal.xy, vec2(cr, sr)), dot(ecNormal.xy, vec2(-sr, cr)));
|
gl_TexCoord[0].x = sign(gl_MultiTexCoord0.x) * rotPitchTex0x.z + gl_MultiTexCoord0.x * tex0yTex1xTex1y.y;
|
||||||
ecNormal = gl_NormalMatrix * ecNormal;
|
gl_TexCoord[0].y = tex0yTex1xTex1y.x + gl_MultiTexCoord0.y * tex0yTex1xTex1y.z;
|
||||||
|
|
||||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
// Rotate the normal.
|
||||||
gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0);
|
ecNormal = gl_Normal;
|
||||||
gl_BackColor = vec4(1.0, 1.0, 1.0, 1.0);
|
|
||||||
alpha = 1.0;
|
// The roof pieces have a normal of (+/-0.7, 0.0, 0.7)
|
||||||
|
// If the roof is flat, then we need to change it to (0,0,1).
|
||||||
|
// First term evaluates for normals without a +z component (all except roof)
|
||||||
|
// Second term evaluates for roof normals with a pitch
|
||||||
|
// Third term evaluates for flat roofs
|
||||||
|
ecNormal = step(0.5, 1.0 - ecNormal.z) * ecNormal +
|
||||||
|
step(0.5, ecNormal.z) * clamp(rotPitchTex0x.y, 0.0, 1.0) * ecNormal +
|
||||||
|
step(0.5, ecNormal.z) * (1.0 - clamp(rotPitchTex0x.y, 0.0, 1.0)) * vec3(0,0,1);
|
||||||
|
|
||||||
|
// Rotate the normal as per the building.
|
||||||
|
ecNormal.xy = vec2(dot(ecNormal.xy, vec2(cr, sr)), dot(ecNormal.xy, vec2(-sr, cr)));
|
||||||
|
ecNormal = gl_NormalMatrix * ecNormal;
|
||||||
|
|
||||||
|
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||||
|
gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||||
|
gl_BackColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||||
|
alpha = 1.0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
// © Emilian Huminiuc and Vivian Meazza 2011
|
// © Emilian Huminiuc and Vivian Meazza 2011
|
||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
|
attribute vec3 instancePosition; // (x,y,z)
|
||||||
|
attribute vec3 instanceScaleRotate; // (width, depth, height)
|
||||||
|
attribute vec3 rotPitchTex0x; // (rotation, pitch height, texture x offset)
|
||||||
|
attribute vec3 tex0yTex1xTex1y; // (texture y offset, texture x gain, texture y gain)
|
||||||
|
|
||||||
varying vec3 rawpos;
|
varying vec3 rawpos;
|
||||||
varying vec3 VNormal;
|
varying vec3 VNormal;
|
||||||
varying vec3 VTangent;
|
varying vec3 VTangent;
|
||||||
|
@ -48,83 +53,105 @@ void rotationMatrixH(in float sinRz, in float cosRz, out mat4 rotmat)
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
float sr = sin(6.28 * gl_Color.a);
|
// Determine the rotation for the building.
|
||||||
float cr = cos(6.28 * gl_Color.a);
|
float sr = sin(6.28 * rotPitchTex0x.x);
|
||||||
rawpos = gl_Vertex.xyz;
|
float cr = cos(6.28 * rotPitchTex0x.x);
|
||||||
|
|
||||||
// Rotation of the object and movement into position
|
// Adjust pitch of roof to the correct height.
|
||||||
rawpos.xy = vec2(dot(rawpos.xy, vec2(cr, sr)), dot(rawpos.xy, vec2(-sr, cr)));
|
// The top roof vertices are the only ones that have fractional z values (1.5),
|
||||||
rawpos = rawpos + gl_Color.xyz;
|
// so we can use this to identify them and scale up any pitched roof vertex to
|
||||||
|
// the correct pitch (rotPitchTex0x.y * 2.0 because of the fractional z value),
|
||||||
|
// then scale down by the building height (instanceScaleRotate.z) because
|
||||||
|
// immediately afterwards we will scale UP the vertex to the correct scale.
|
||||||
|
rawpos = gl_Vertex.xyz;
|
||||||
|
rawpos.z = rawpos.z + fract(rawpos.z) * 2.0 * rotPitchTex0x.y / instanceScaleRotate.z - fract(rawpos.z);
|
||||||
|
rawpos = rawpos * instanceScaleRotate.xyz;
|
||||||
|
|
||||||
vec4 ecPosition = gl_ModelViewMatrix * vec4(rawpos.x, rawpos.y, rawpos.z, 1.0);
|
// Rotation of the building and movement into rawpos
|
||||||
//fog_Func(fogType);
|
rawpos.xy = vec2(dot(rawpos.xy, vec2(cr, sr)), dot(rawpos.xy, vec2(-sr, cr)));
|
||||||
|
rawpos = rawpos + instancePosition.xyz;
|
||||||
|
vec4 ecPosition = gl_ModelViewMatrix * vec4(rawpos, 1.0);
|
||||||
|
|
||||||
// Rotate the normal.
|
// Texture coordinates are stored as tex0 and tex1 across two attributes.
|
||||||
vec3 normal = gl_Normal;
|
// tex0 contains the bottom leftmost point, and tex1 contains (w,h).
|
||||||
normal.xy = vec2(dot(normal.xy, vec2(cr, sr)), dot(normal.xy, vec2(-sr, cr)));
|
gl_TexCoord[0].x = sign(gl_MultiTexCoord0.x) * rotPitchTex0x.z + gl_MultiTexCoord0.x * tex0yTex1xTex1y.y;
|
||||||
//normal = gl_NormalMatrix * normal;
|
gl_TexCoord[0].y = tex0yTex1xTex1y.x + gl_MultiTexCoord0.y * tex0yTex1xTex1y.z;
|
||||||
|
|
||||||
VNormal = normalize(gl_NormalMatrix * normal);
|
// Rotate the normal.
|
||||||
vec3 n = normalize(normal);
|
vec3 normal = gl_Normal;
|
||||||
vec3 tempTangent = cross(n, vec3(1.0,0.0,0.0));
|
|
||||||
vec3 tempBinormal = cross(n, tempTangent);
|
|
||||||
|
|
||||||
if (nmap_enabled > 0){
|
// The roof pieces have a normal of (+/-0.7, 0.0, 0.7)
|
||||||
tempTangent = tangent;
|
// If the roof is flat, then we need to change it to (0,0,1).
|
||||||
tempBinormal = binormal;
|
// First term evaluates for normals without a +z component (all except roof)
|
||||||
}
|
// Second term evaluates for roof normals with a pitch
|
||||||
|
// Third term evaluates for flat roofs
|
||||||
|
normal = step(0.5, 1.0 - normal.z) * normal +
|
||||||
|
step(0.5, normal.z) * clamp(rotPitchTex0x.y, 0.0, 1.0) * normal +
|
||||||
|
step(0.5, normal.z) * (1.0 - clamp(rotPitchTex0x.y, 0.0, 1.0)) * vec3(0,0,1);
|
||||||
|
|
||||||
VTangent = normalize(gl_NormalMatrix * tempTangent);
|
// Rotate the normal as per the building.
|
||||||
VBinormal = normalize(gl_NormalMatrix * tempBinormal);
|
normal.xy = vec2(dot(normal.xy, vec2(cr, sr)), dot(normal.xy, vec2(-sr, cr)));
|
||||||
vec3 t = tempTangent;
|
|
||||||
vec3 b = tempBinormal;
|
|
||||||
|
|
||||||
// Super hack: if diffuse material alpha is less than 1, assume a
|
VNormal = normalize(gl_NormalMatrix * normal);
|
||||||
// transparency animation is at work
|
vec3 n = normalize(normal);
|
||||||
if (gl_FrontMaterial.diffuse.a < 1.0)
|
vec3 tempTangent = cross(n, vec3(1.0,0.0,0.0));
|
||||||
alpha = gl_FrontMaterial.diffuse.a;
|
vec3 tempBinormal = cross(n, tempTangent);
|
||||||
else
|
|
||||||
alpha = 1.0;
|
|
||||||
|
|
||||||
// Vertex in eye coordinates
|
if (nmap_enabled > 0){
|
||||||
vertVec = ecPosition.xyz;
|
tempTangent = tangent;
|
||||||
vViewVec.x = dot(t, vertVec);
|
tempBinormal = binormal;
|
||||||
vViewVec.y = dot(b, vertVec);
|
}
|
||||||
vViewVec.z = dot(n, vertVec);
|
|
||||||
|
|
||||||
// calculate the reflection vector
|
VTangent = normalize(gl_NormalMatrix * tempTangent);
|
||||||
vec4 reflect_eye = vec4(reflect(vertVec, VNormal), 0.0);
|
VBinormal = normalize(gl_NormalMatrix * tempBinormal);
|
||||||
vec3 reflVec_stat = normalize(gl_ModelViewMatrixInverse * reflect_eye).xyz;
|
vec3 t = tempTangent;
|
||||||
if (refl_dynamic > 0){
|
vec3 b = tempBinormal;
|
||||||
//prepare rotation matrix
|
|
||||||
mat4 RotMatPR;
|
|
||||||
mat4 RotMatH;
|
|
||||||
float _roll = roll;
|
|
||||||
if (_roll>90.0 || _roll < -90.0)
|
|
||||||
{
|
|
||||||
_roll = -_roll;
|
|
||||||
}
|
|
||||||
float cosRx = cos(radians(_roll));
|
|
||||||
float sinRx = sin(radians(_roll));
|
|
||||||
float cosRy = cos(radians(-pitch));
|
|
||||||
float sinRy = sin(radians(-pitch));
|
|
||||||
float cosRz = cos(radians(hdg));
|
|
||||||
float sinRz = sin(radians(hdg));
|
|
||||||
rotationMatrixPR(sinRx, cosRx, sinRy, cosRy, RotMatPR);
|
|
||||||
rotationMatrixH(sinRz, cosRz, RotMatH);
|
|
||||||
vec3 reflVec_dyn = (RotMatH * (RotMatPR * normalize(gl_ModelViewMatrixInverse * reflect_eye))).xyz;
|
|
||||||
|
|
||||||
reflVec = reflVec_dyn;
|
// Super hack: if diffuse material alpha is less than 1, assume a
|
||||||
} else {
|
// transparency animation is at work
|
||||||
reflVec = reflVec_stat;
|
if (gl_FrontMaterial.diffuse.a < 1.0)
|
||||||
|
alpha = gl_FrontMaterial.diffuse.a;
|
||||||
|
else
|
||||||
|
alpha = 1.0;
|
||||||
|
|
||||||
|
// Vertex in eye coordinates
|
||||||
|
vertVec = ecPosition.xyz;
|
||||||
|
vViewVec.x = dot(t, vertVec);
|
||||||
|
vViewVec.y = dot(b, vertVec);
|
||||||
|
vViewVec.z = dot(n, vertVec);
|
||||||
|
|
||||||
|
// calculate the reflection vector
|
||||||
|
vec4 reflect_eye = vec4(reflect(vertVec, VNormal), 0.0);
|
||||||
|
vec3 reflVec_stat = normalize(gl_ModelViewMatrixInverse * reflect_eye).xyz;
|
||||||
|
if (refl_dynamic > 0){
|
||||||
|
//prepare rotation matrix
|
||||||
|
mat4 RotMatPR;
|
||||||
|
mat4 RotMatH;
|
||||||
|
float _roll = roll;
|
||||||
|
if (_roll>90.0 || _roll < -90.0)
|
||||||
|
{
|
||||||
|
_roll = -_roll;
|
||||||
}
|
}
|
||||||
|
float cosRx = cos(radians(_roll));
|
||||||
|
float sinRx = sin(radians(_roll));
|
||||||
|
float cosRy = cos(radians(-pitch));
|
||||||
|
float sinRy = sin(radians(-pitch));
|
||||||
|
float cosRz = cos(radians(hdg));
|
||||||
|
float sinRz = sin(radians(hdg));
|
||||||
|
rotationMatrixPR(sinRx, cosRx, sinRy, cosRy, RotMatPR);
|
||||||
|
rotationMatrixH(sinRz, cosRz, RotMatH);
|
||||||
|
vec3 reflVec_dyn = (RotMatH * (RotMatPR * normalize(gl_ModelViewMatrixInverse * reflect_eye))).xyz;
|
||||||
|
|
||||||
if(rembrandt_enabled < 1){
|
reflVec = reflVec_dyn;
|
||||||
gl_FrontColor = gl_FrontMaterial.emission + vec4(1.0,1.0,1.0,1.0)
|
} else {
|
||||||
* (gl_LightModel.ambient + gl_LightSource[0].ambient);
|
reflVec = reflVec_stat;
|
||||||
} else {
|
}
|
||||||
gl_FrontColor = vec4(1.0,1.0,1.0,1.0);
|
|
||||||
}
|
if(rembrandt_enabled < 1){
|
||||||
gl_Position = gl_ModelViewProjectionMatrix * vec4(rawpos,1.0);
|
gl_FrontColor = gl_FrontMaterial.emission + vec4(1.0,1.0,1.0,1.0)
|
||||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
* (gl_LightModel.ambient + gl_LightSource[0].ambient);
|
||||||
|
} else {
|
||||||
|
gl_FrontColor = vec4(1.0,1.0,1.0,1.0);
|
||||||
|
}
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * vec4(rawpos,1.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,53 +3,77 @@
|
||||||
// Licence: GPL v2
|
// Licence: GPL v2
|
||||||
// © Emilian Huminiuc and Vivian Meazza 2011
|
// © Emilian Huminiuc and Vivian Meazza 2011
|
||||||
#version 120
|
#version 120
|
||||||
|
#extension GL_EXT_draw_instanced : enable
|
||||||
|
|
||||||
varying vec4 diffuseColor;
|
varying vec4 diffuseColor;
|
||||||
varying vec3 VBinormal;
|
varying vec3 VBinormal;
|
||||||
varying vec3 VNormal;
|
varying vec3 VNormal;
|
||||||
varying vec3 VTangent;
|
varying vec3 VTangent;
|
||||||
varying vec3 rawpos;
|
|
||||||
varying vec3 eyeVec;
|
varying vec3 eyeVec;
|
||||||
|
varying vec3 normal;
|
||||||
|
|
||||||
uniform int refl_dynamic;
|
uniform int refl_dynamic;
|
||||||
uniform int nmap_enabled;
|
uniform int nmap_enabled;
|
||||||
uniform int shader_qual;
|
uniform int shader_qual;
|
||||||
uniform int rembrandt_enabled;
|
uniform int rembrandt_enabled;
|
||||||
|
|
||||||
|
attribute vec3 instancePosition; // (x,y,z)
|
||||||
|
attribute vec3 instanceScaleRotate; // (width, depth, height)
|
||||||
|
attribute vec3 rotPitchTex0x; // (rotation, pitch height, texture x offset)
|
||||||
|
attribute vec3 tex0yTex1xTex1y; // (texture y offset, texture x gain, texture y gain)
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
float sr = sin(6.28 * gl_Color.a);
|
// Determine the rotation for the building.
|
||||||
float cr = cos(6.28 * gl_Color.a);
|
float sr = sin(6.28 * rotPitchTex0x.x);
|
||||||
rawpos = gl_Vertex.xyz;
|
float cr = cos(6.28 * rotPitchTex0x.x);
|
||||||
|
|
||||||
// Rotation of the object and movement into position
|
// Adjust pitch of roof to the correct height.
|
||||||
rawpos.xy = vec2(dot(rawpos.xy, vec2(cr, sr)), dot(rawpos.xy, vec2(-sr, cr)));
|
// The top roof vertices are the only ones that have fractional z values (1.5),
|
||||||
rawpos = rawpos + gl_Color.xyz;
|
// so we can use this to identify them and scale up any pitched roof vertex to
|
||||||
|
// the correct pitch (rotPitchTex0x.y * 2.0 because of the fractional z value),
|
||||||
|
// then scale down by the building height (instanceScaleRotate.z) because
|
||||||
|
// immediately afterwards we will scale UP the vertex to the correct scale.
|
||||||
|
vec3 position = gl_Vertex.xyz;
|
||||||
|
position.z = position.z + fract(position.z) * 2.0 * rotPitchTex0x.y / instanceScaleRotate.z - fract(position.z);
|
||||||
|
position = position * instanceScaleRotate.xyz;
|
||||||
|
|
||||||
vec4 ecPosition = gl_ModelViewMatrix * vec4(rawpos.xyz, 1.0);
|
// Rotation of the building and movement into position
|
||||||
|
position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr)));
|
||||||
|
position = position + instancePosition.xyz;
|
||||||
|
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
|
||||||
|
vec4 ecPosition = gl_ModelViewMatrix * vec4(position, 1.0);
|
||||||
|
|
||||||
eyeVec = ecPosition.xyz;
|
eyeVec = ecPosition.xyz;
|
||||||
|
|
||||||
// Rotate the normal.
|
// Rotate the normal.
|
||||||
vec3 normal = gl_Normal;
|
normal = gl_Normal;
|
||||||
normal.xy = vec2(dot(normal.xy, vec2(cr, sr)), dot(normal.xy, vec2(-sr, cr)));
|
|
||||||
|
|
||||||
VNormal = normalize(gl_NormalMatrix * normal);
|
// The roof pieces have a normal of (+/-0.7, 0.0, 0.7)
|
||||||
vec3 n = normalize(normal);
|
// If the roof is flat, then we need to change it to (0,0,1).
|
||||||
vec3 c1 = cross(n, vec3(0.0,0.0,1.0));
|
// First term evaluates for normals without a +z component (all except roof)
|
||||||
vec3 c2 = cross(n, vec3(0.0,1.0,0.0));
|
// Second term evaluates for roof normals with a pitch
|
||||||
|
// Third term evaluates for flat roofs
|
||||||
|
normal = step(0.5, 1.0 - normal.z) * normal + step(0.5, normal.z) * clamp(rotPitchTex0x.y, 0.0, 1.0) * normal + step(0.5, normal.z) * (1.0 - clamp(rotPitchTex0x.y, 0.0, 1.0)) * vec3(0,0,1);
|
||||||
|
|
||||||
VTangent = c1;
|
// Rotate the normal as per the building.
|
||||||
if(length(c2)>length(c1)){
|
normal.xy = vec2(dot(normal.xy, vec2(cr, sr)), dot(normal.xy, vec2(-sr, cr)));
|
||||||
VTangent = c2;
|
vec3 n = normalize(normal);
|
||||||
}
|
|
||||||
|
|
||||||
VBinormal = cross(n, VTangent);
|
vec3 c1 = cross(n, vec3(0.0,0.0,1.0));
|
||||||
|
vec3 c2 = cross(n, vec3(0.0,1.0,0.0));
|
||||||
|
VNormal = normalize(gl_NormalMatrix * normal);
|
||||||
|
|
||||||
VTangent = normalize(gl_NormalMatrix * -VTangent);
|
VTangent = c1;
|
||||||
VBinormal = normalize(gl_NormalMatrix * VBinormal);
|
if(length(c2)>length(c1)){
|
||||||
|
VTangent = c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
VBinormal = cross(n, VTangent);
|
||||||
|
|
||||||
|
VTangent = normalize(gl_NormalMatrix * -VTangent);
|
||||||
|
VBinormal = normalize(gl_NormalMatrix * VBinormal);
|
||||||
|
|
||||||
// Force no alpha on random buildings
|
// Force no alpha on random buildings
|
||||||
diffuseColor = vec4(gl_FrontMaterial.diffuse.rgb,1.0);
|
diffuseColor = vec4(gl_FrontMaterial.diffuse.rgb,1.0);
|
||||||
|
@ -60,7 +84,10 @@ void main(void)
|
||||||
} else {
|
} else {
|
||||||
gl_FrontColor = vec4(1.0);
|
gl_FrontColor = vec4(1.0);
|
||||||
}
|
}
|
||||||
gl_Position = gl_ModelViewProjectionMatrix * vec4(rawpos,1.0);
|
|
||||||
gl_ClipVertex = ecPosition;
|
gl_ClipVertex = ecPosition;
|
||||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
|
||||||
|
// Texture coordinates are stored as tex0 and tex1 across two attributes.
|
||||||
|
// tex0 contains the bottom leftmost point, and tex1 contains (w,h).
|
||||||
|
gl_TexCoord[0].x = sign(gl_MultiTexCoord0.x) * rotPitchTex0x.z + gl_MultiTexCoord0.x * tex0yTex1xTex1y.y;
|
||||||
|
gl_TexCoord[0].y = tex0yTex1xTex1y.x + gl_MultiTexCoord0.y * tex0yTex1xTex1y.z;
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 702 KiB After Width: | Height: | Size: 876 KiB |
Before Width: | Height: | Size: 722 KiB After Width: | Height: | Size: 1.4 MiB |
Before Width: | Height: | Size: 381 KiB After Width: | Height: | Size: 323 KiB |
Before Width: | Height: | Size: 2.7 MiB After Width: | Height: | Size: 2.4 MiB |
|
@ -8,7 +8,7 @@
|
||||||
"helvetica_bold.txf". "size" and "slant" take only effect on
|
"helvetica_bold.txf". "size" and "slant" take only effect on
|
||||||
texture fonts.
|
texture fonts.
|
||||||
-->
|
-->
|
||||||
<style-name>Anthrax</style-name>
|
<name>Anthrax</name>
|
||||||
<fonts>
|
<fonts>
|
||||||
<gui>
|
<gui>
|
||||||
<name type="string">HELVETICA_12</name>
|
<name type="string">HELVETICA_12</name>
|
||||||
|
|