1
0
Fork 0

Merge branch 'master' of gitorious.org:fg/fgdata

This commit is contained in:
Durk Talsma 2011-10-07 17:48:10 +02:00
commit 61c5c35ff4
16 changed files with 442 additions and 128 deletions

View file

@ -43,8 +43,6 @@ The cloud is defined by the following properties:
<height-map-texture> - whether to choose the vertical texture index based on <height-map-texture> - whether to choose the vertical texture index based on
sprite height within the clouds (default false) sprite height within the clouds (default false)
<num-sprites> - Number of sprite to generate for the cloud (default 20) <num-sprites> - Number of sprite to generate for the cloud (default 20)
<bottom-shade> - Light multiplier for sprites at the bottom of the cloud
(default 1.0)
<min-sprite-width-m> - minimum width of the sprites used to create the cloud <min-sprite-width-m> - minimum width of the sprites used to create the cloud
(default 200) (default 200)
<max-sprite-width-m> - maximum width of the sprites used to create the cloud <max-sprite-width-m> - maximum width of the sprites used to create the cloud
@ -56,7 +54,39 @@ The cloud is defined by the following properties:
<z-scale> - vertical scaling factor to apply to to the sprite after <z-scale> - vertical scaling factor to apply to to the sprite after
billboarding. A small value would create a sprite that billboarding. A small value would create a sprite that
looks squashed when viewed from the side. (default 1.0) looks squashed when viewed from the side. (default 1.0)
<min-bottom-lighting-factor> - See Shading below (default 1.0)
<max-bottom-lighting-factor> - See Shading below (default min-...-factor + 0.1)
<min-middle-lighting-factor> - See Shading below (default 1.0)
<max-middle-lighting-factor> - See Shading below (default min-...-factor + 0.1)
<min-top-lighting-factor> - See Shading below (default 1.0)
<max-top-lighting-factor> - See Shading below (default min-...-factor + 0.1)
<min-shade-lighting-factor> - See Shading below (default 0.5)
<max-shade-lighting-factor> - See Shading below (default min-...-factor + 0.1)
Shading
-------
the [min|max]-...-lighting-factor properties allow you to define diffuse lighting
multipliers to the bottom, middle, top, sunny and shaded parts of the cloud. In
each case, individual clouds will have a random multiplier between the min and
max values used to allow for some variation between individual clouds.
The top, middle and bottom lighting factors are applied based on the pixels vertical
positon in the cloud. A linear interpolation is used either between top/middle (if
the pixel is above the middle of the cloud) or middle/bottom (if the pixel is below
the middle of the cloud).
The top factor is also applied to _all_ pixels on the sunny side of the cloud. The
shade factor is applied based on the pixel position away from the sun, linearly
interpolated from top to shade. E.g this is not a straight linear interpolation
from top to shade across the entire cloud.
The final lighting factor is determined by the minimum of the vertical factor and
the sunny/shade factor. Note that this is applied to the individual pixels, not
sprites.
Textures
--------
The texture to use for the sprites is defined in the <texture> tag. The texture to use for the sprites is defined in the <texture> tag.
To allow some variation, you can create a texture file containing multiple To allow some variation, you can create a texture file containing multiple

View file

@ -60,6 +60,10 @@
<name>usrAttr2</name> <name>usrAttr2</name>
<index>11</index> <index>11</index>
</attribute> </attribute>
<attribute>
<name>usrAttr3</name>
<index>12</index>
</attribute>
</program> </program>
<uniform> <uniform>
<name>baseTexture</name> <name>baseTexture</name>

View file

@ -12,7 +12,9 @@
</texture> </texture>
<texture n="2"> <texture n="2">
<!--<image>Textures/Water/water-normalmap.png</image>--> <!--<image>Textures/Water/water-normalmap.png</image>-->
<image>Textures/Water/normalmap2.png</image> <!--<image>Textures/Water/water-normalmap2.dds</image>-->
<image>Textures/Water/waves-ver10-nm.dds</image>
<!--<image>Textures/Water/caustic-nm.png</image>-->
<filter>linear-mipmap-linear</filter> <filter>linear-mipmap-linear</filter>
<wrap-s>repeat</wrap-s> <wrap-s>repeat</wrap-s>
<wrap-t>repeat</wrap-t> <wrap-t>repeat</wrap-t>
@ -20,7 +22,9 @@
</texture> </texture>
<texture n="3"> <texture n="3">
<!--<image>Textures/Water/water-dudv.png</image>--> <!--<image>Textures/Water/water-dudv.png</image>-->
<image>Textures/Water/dudvmap2.png</image> <!--<image>Textures/Water/dudvmap2.png</image>-->
<image>Textures/Water/waves-ver10-dudv.dds</image>
<!--<image>Textures/Water/water-reflection-grey.png</image>-->
<filter>linear-mipmap-linear</filter> <filter>linear-mipmap-linear</filter>
<wrap-s>repeat</wrap-s> <wrap-s>repeat</wrap-s>
<wrap-t>repeat</wrap-t> <wrap-t>repeat</wrap-t>
@ -34,7 +38,14 @@
<internal-format>normalized</internal-format> <internal-format>normalized</internal-format>
</texture> </texture>
<texture n="5"> <texture n="5">
<image>Textures/Water/sea_foam.png</image> <image>Textures/Water/sea_foam.dds</image>
<filter>linear-mipmap-linear</filter>
<wrap-s>repeat</wrap-s>
<wrap-t>repeat</wrap-t>
<internal-format>normalized</internal-format>
</texture>
<texture n="6">
<image>Textures/Water/perlin-noise-nm.dds</image>
<filter>linear-mipmap-linear</filter> <filter>linear-mipmap-linear</filter>
<wrap-s>repeat</wrap-s> <wrap-s>repeat</wrap-s>
<wrap-t>repeat</wrap-t> <wrap-t>repeat</wrap-t>
@ -73,6 +84,10 @@
<windN> <windN>
<use>/environment/config/boundary/entry[0]/wind-from-north-fps</use> <use>/environment/config/boundary/entry[0]/wind-from-north-fps</use>
</windN> </windN>
<wind-from>
<use>/environment/config/boundary/entry[0]/wind-from-heading-deg</use>
</wind-from>
</parameters> </parameters>
<technique n="8"> <technique n="8">
@ -218,6 +233,28 @@
<use>texture[5]/internal-format</use> <use>texture[5]/internal-format</use>
</internal-format> </internal-format>
</texture-unit> </texture-unit>
<texture-unit>
<unit>6</unit>
<image>
<use>texture[6]/image</use>
</image>
<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>
<texture-unit>
<unit>9</unit>
<type>noise</type>
</texture-unit>
<program> <program>
<vertex-shader>Shaders/water.vert</vertex-shader> <vertex-shader>Shaders/water.vert</vertex-shader>
<fragment-shader>Shaders/water.frag</fragment-shader> <fragment-shader>Shaders/water.frag</fragment-shader>
@ -247,6 +284,11 @@
<type>sampler-2d</type> <type>sampler-2d</type>
<value type="int">5</value> <value type="int">5</value>
</uniform> </uniform>
<uniform>
<name>perlin_normalmap</name>
<type>sampler-2d</type>
<value type="int">6</value>
</uniform>
<uniform> <uniform>
<name>saturation</name> <name>saturation</name>
<type>float</type> <type>float</type>
@ -317,6 +359,18 @@
<use>windN</use> <use>windN</use>
</value> </value>
</uniform> </uniform>
<uniform>
<name>WindFrom</name>
<type>float</type>
<value>
<use>wind-from</use>
</value>
</uniform>
<uniform>
<name>Noise</name>
<type>sampler-3d</type>
<value type="int">9</value>
</uniform>
</pass> </pass>
</technique> </technique>
<technique n="9"> <technique n="9">

View file

@ -35,33 +35,29 @@ ns = Nimbostratus (Rain cloud)
<clouds> <clouds>
<cb-large> <cb-large>
<min-cloud-width-m>1600</min-cloud-width-m> <min-cloud-width-m>1600</min-cloud-width-m>
<max-cloud-width-m>2000</max-cloud-width-m>
<min-cloud-height-m>4000</min-cloud-height-m> <min-cloud-height-m>4000</min-cloud-height-m>
<max-cloud-height-m>3000</max-cloud-height-m>
<num-sprites>10</num-sprites> <num-sprites>10</num-sprites>
<texture>cl_cumulus.png</texture> <texture>cl_cumulus.png</texture>
<num-textures-x>4</num-textures-x> <num-textures-x>4</num-textures-x>
<num-textures-y>4</num-textures-y> <num-textures-y>4</num-textures-y>
<bottom-shade>0.3</bottom-shade> <min-bottom-lighting-factor>0.3</min-bottom-lighting-factor>
<min-shade-lighting-factor>0.4</min-shade-lighting-factor>
<min-sprite-width-m>800</min-sprite-width-m> <min-sprite-width-m>800</min-sprite-width-m>
<max-sprite-width-m>1200</max-sprite-width-m>
<min-sprite-height-m>800</min-sprite-height-m> <min-sprite-height-m>800</min-sprite-height-m>
<max-sprite-height-m>1200</max-sprite-height-m> <height-map-texture>true</height-map-texture>
</cb-large> </cb-large>
<cb-small> <cb-small>
<min-cloud-width-m>800</min-cloud-width-m> <min-cloud-width-m>800</min-cloud-width-m>
<max-cloud-width-m>400</max-cloud-width-m> <min-cloud-height-m>800</min-cloud-height-m>
<min-cloud-height-m>500</min-cloud-height-m>
<max-cloud-height-m>200</max-cloud-height-m>
<num-sprites>10</num-sprites> <num-sprites>10</num-sprites>
<texture>cl_cumulus.png</texture> <texture>cl_cumulus.png</texture>
<num-textures-x>4</num-textures-x> <num-textures-x>4</num-textures-x>
<num-textures-y>4</num-textures-y> <num-textures-y>4</num-textures-y>
<bottom-shade>0.3</bottom-shade> <min-bottom-lighting-factor>0.3</min-bottom-lighting-factor>
<min-shade-lighting-factor>0.4</min-shade-lighting-factor>
<min-sprite-width-m>400</min-sprite-width-m> <min-sprite-width-m>400</min-sprite-width-m>
<max-sprite-width-m>800</max-sprite-width-m>
<min-sprite-height-m>400</min-sprite-height-m> <min-sprite-height-m>400</min-sprite-height-m>
<max-sprite-height-m>800</max-sprite-height-m> <height-map-texture>true</height-map-texture>
</cb-small> </cb-small>
<cu-large> <cu-large>
<min-cloud-width-m>600</min-cloud-width-m> <min-cloud-width-m>600</min-cloud-width-m>
@ -69,89 +65,95 @@ ns = Nimbostratus (Rain cloud)
<min-cloud-height-m>400</min-cloud-height-m> <min-cloud-height-m>400</min-cloud-height-m>
<max-cloud-height-m>800</max-cloud-height-m> <max-cloud-height-m>800</max-cloud-height-m>
<num-sprites>20</num-sprites> <num-sprites>20</num-sprites>
<texture>cl_cumulus.png</texture> <texture>cl_cumulus2.png</texture>
<num-textures-x>4</num-textures-x> <num-textures-x>4</num-textures-x>
<num-textures-y>4</num-textures-y> <num-textures-y>4</num-textures-y>
<bottom-shade>0.6</bottom-shade> <min-bottom-lighting-factor>0.2</min-bottom-lighting-factor>
<min-shade-lighting-factor>0.3</min-shade-lighting-factor>
<min-sprite-width-m>400</min-sprite-width-m> <min-sprite-width-m>400</min-sprite-width-m>
<max-sprite-width-m>700</max-sprite-width-m> <max-sprite-width-m>700</max-sprite-width-m>
<min-sprite-height-m>300</min-sprite-height-m> <min-sprite-height-m>300</min-sprite-height-m>
<max-sprite-height-m>700</max-sprite-height-m> <max-sprite-height-m>700</max-sprite-height-m>
<height-map-texture>true</height-map-texture>
</cu-large> </cu-large>
<cu-small> <cu-small>
<min-cloud-width-m>300</min-cloud-width-m> <min-cloud-width-m>600</min-cloud-width-m>
<max-cloud-width-m>800</max-cloud-width-m> <max-cloud-width-m>900</max-cloud-width-m>
<min-cloud-height-m>200</min-cloud-height-m> <min-cloud-height-m>400</min-cloud-height-m>
<max-cloud-height-m>300</max-cloud-height-m> <max-cloud-height-m>600</max-cloud-height-m>
<num-sprites>10</num-sprites> <num-sprites>20</num-sprites>
<texture>cl_cumulus.png</texture> <texture>cl_cumulus2.png</texture>
<num-textures-x>4</num-textures-x> <num-textures-x>4</num-textures-x>
<num-textures-y>4</num-textures-y> <num-textures-y>4</num-textures-y>
<bottom-shade>0.7</bottom-shade> <min-bottom-lighting-factor>0.4</min-bottom-lighting-factor>
<min-sprite-width-m>200</min-sprite-width-m> <min-shade-lighting-factor>0.5</min-shade-lighting-factor>
<min-sprite-width-m>300</min-sprite-width-m>
<max-sprite-width-m>400</max-sprite-width-m> <max-sprite-width-m>400</max-sprite-width-m>
<min-sprite-height-m>150</min-sprite-height-m> <min-sprite-height-m>200</min-sprite-height-m>
<max-sprite-height-m>300</max-sprite-height-m> <max-sprite-height-m>300</max-sprite-height-m>
<height-map-texture>true</height-map-texture>
</cu-small> </cu-small>
<ns-large> <ns-large>
<min-cloud-width-m>1200</min-cloud-width-m> <min-cloud-width-m>1200</min-cloud-width-m>
<max-cloud-width-m>3000</max-cloud-width-m> <max-cloud-width-m>3000</max-cloud-width-m>
<min-cloud-height-m>200</min-cloud-height-m> <min-cloud-height-m>400</min-cloud-height-m>
<max-cloud-height-m>400</max-cloud-height-m> <max-cloud-height-m>800</max-cloud-height-m>
<num-sprites>40</num-sprites> <num-sprites>40</num-sprites>
<texture>cl_st.png</texture> <texture>cl_st.png</texture>
<num-textures-x>1</num-textures-x> <num-textures-x>1</num-textures-x>
<num-textures-y>1</num-textures-y> <num-textures-y>1</num-textures-y>
<bottom-shade>0.2</bottom-shade> <min-bottom-lighting-factor>0.2</min-bottom-lighting-factor>
<min-sprite-width-m>300</min-sprite-width-m> <min-sprite-width-m>300</min-sprite-width-m>
<max-sprite-width-m>600</max-sprite-width-m> <max-sprite-width-m>600</max-sprite-width-m>
<min-sprite-height-m>100</min-sprite-height-m> <min-sprite-height-m>100</min-sprite-height-m>
<max-sprite-height-m>200</max-sprite-height-m> <max-sprite-height-m>200</max-sprite-height-m>
<height-map-texture>false</height-map-texture>
<z-scale>0.5</z-scale>
</ns-large> </ns-large>
<ns-white> <ns-white>
<min-cloud-width-m>600</min-cloud-width-m> <min-cloud-width-m>600</min-cloud-width-m>
<max-cloud-width-m>2000</max-cloud-width-m> <max-cloud-width-m>2000</max-cloud-width-m>
<min-cloud-height-m>200</min-cloud-height-m> <min-cloud-height-m>400</min-cloud-height-m>
<max-cloud-height-m>300</max-cloud-height-m> <max-cloud-height-m>600</max-cloud-height-m>
<num-sprites>40</num-sprites> <num-sprites>40</num-sprites>
<texture>cl_st.png</texture> <texture>cl_st.png</texture>
<num-textures-x>1</num-textures-x> <num-textures-x>1</num-textures-x>
<num-textures-y>1</num-textures-y> <num-textures-y>1</num-textures-y>
<bottom-shade>0.3</bottom-shade> <min-bottom-lighting-factor>0.3</min-bottom-lighting-factor>
<min-sprite-width-m>300</min-sprite-width-m> <min-sprite-width-m>300</min-sprite-width-m>
<max-sprite-width-m>600</max-sprite-width-m> <max-sprite-width-m>600</max-sprite-width-m>
<min-sprite-height-m>100</min-sprite-height-m> <min-sprite-height-m>100</min-sprite-height-m>
<max-sprite-height-m>200</max-sprite-height-m> <max-sprite-height-m>200</max-sprite-height-m>
<height-map-texture>false</height-map-texture>
<z-scale>0.5</z-scale>
</ns-white> </ns-white>
<st-small> <st-small>
<min-cloud-width-m>800</min-cloud-width-m> <min-cloud-width-m>1000</min-cloud-width-m>
<max-cloud-width-m>1500</max-cloud-width-m>
<min-cloud-height-m>100</min-cloud-height-m>
<max-cloud-height-m>200</max-cloud-height-m>
<num-sprites>40</num-sprites>
<texture>cl_st.png</texture>
<num-textures-x>1</num-textures-x>
<num-textures-y>1</num-textures-y>
<bottom-shade>0.9</bottom-shade>
<min-sprite-width-m>300</min-sprite-width-m>
<max-sprite-width-m>600</max-sprite-width-m>
<min-sprite-height-m>200</min-sprite-height-m>
<max-sprite-height-m>400</max-sprite-height-m>
</st-small>
<st-large>
<min-cloud-width-m>1800</min-cloud-width-m>
<max-cloud-width-m>2500</max-cloud-width-m>
<min-cloud-height-m>200</min-cloud-height-m> <min-cloud-height-m>200</min-cloud-height-m>
<max-cloud-height-m>400</max-cloud-height-m>
<num-sprites>40</num-sprites> <num-sprites>40</num-sprites>
<texture>cl_st.png</texture> <texture>cl_cumulus.png</texture>
<num-textures-x>1</num-textures-x> <num-textures-x>4</num-textures-x>
<num-textures-y>1</num-textures-y> <num-textures-y>4</num-textures-y>
<bottom-shade>0.9</bottom-shade> <min-bottom-lighting-factor>0.9</min-bottom-lighting-factor>
<min-sprite-width-m>400</min-sprite-width-m> <min-sprite-width-m>400</min-sprite-width-m>
<max-sprite-width-m>800</max-sprite-width-m> <max-sprite-width-m>800</max-sprite-width-m>
<min-sprite-height-m>300</min-sprite-height-m> <min-sprite-height-m>400</min-sprite-height-m>
<max-sprite-height-m>500</max-sprite-height-m> <max-sprite-height-m>800</max-sprite-height-m>
<height-map-texture>false</height-map-texture>
<z-scale>0.3</z-scale>
</st-small>
<st-large>
<min-cloud-width-m>2000</min-cloud-width-m>
<min-cloud-height-m>1000</min-cloud-height-m>
<num-sprites>40</num-sprites>
<texture>cl_st.png</texture>
<num-textures-x>1</num-textures-x>
<num-textures-y>1</num-textures-y>
<min-bottom-lighting-factor>0.9</min-bottom-lighting-factor>
<min-sprite-width-m>600</min-sprite-width-m>
<min-sprite-height-m>600</min-sprite-height-m>
<height-map-texture>false</height-map-texture>
<z-scale>0.4</z-scale>
</st-large> </st-large>
</clouds> </clouds>
<boxes> <boxes>

View file

@ -7,6 +7,65 @@
## ##
############################################################################### ###############################################################################
###############################################################################
# Event broadcast channel using a MP enabled string property.
# Events from users in multiplayer.ignore are ignored.
#
# EventChannel.new(mpp_path)
# Create a new event broadcast channel. Any MP user with the same
# primitive will receive all messages sent to the channel from the point
# she/he joined (barring severe MP packet loss).
# NOTE: Message delivery is not guaranteed.
# mpp_path - MP property path : string
#
# EventChannel.register(event_hash, handler)
# Register a handler for the event identified by the hash event_hash.
# event_hash - hash value for the event : a unique 4 character string
# handler - a handler function for the event : func (msg)
#
# EventChannel.deregister(event_hash)
# Deregister the handler for the event identified by the hash event_hash.
# event_hash - hash value for the event : a unique 4 character string
#
# EventChannel.send(event_hash, msg)
# Sends the event event_hash with the message msg to the channel.
# event_hash - hash value for the event : a unique 4 character string
# msg - text string with Binary data encoded data : string
#
# EventChannel.die()
# Destroy this EventChannel instance.
#
var EventChannel = {};
EventChannel.new = func (mpp_path) {
var obj = BroadcastChannel.new(mpp_path,
func (n, msg) { obj._process(n, msg) });
# Save send from being overriden.
obj.parent_send = obj.send;
# Put EventChannel methods before BroadcastChannel methods.
obj.parents = [EventChannel] ~ obj.parents;
obj.events = {};
return obj;
}
EventChannel.register = func (event_hash,
handler) {
me.events[event_hash] = handler;
}
EventChannel.deregister = func (event_hash) {
delete(me.events, event_hash);
}
EventChannel.send = func (event_hash,
msg) {
me.parent_send(event_hash ~ msg);
}
############################################################
# Internals.
EventChannel._process = func (n, msg) {
var event_hash = Binary.readHash(msg);
if (contains(me.events, event_hash)) {
me.events[event_hash](substr(msg, Binary.sizeOf["Hash"]));
}
}
############################################################################### ###############################################################################
# Broadcast primitive using a MP enabled string property. # Broadcast primitive using a MP enabled string property.
# Broadcasts from users in multiplayer.ignore are ignored. # Broadcasts from users in multiplayer.ignore are ignored.
@ -60,6 +119,7 @@ BroadcastChannel.new = func (mpp_path, process,
send_buf : [], send_buf : [],
peers : {}, peers : {},
loopid : 0, loopid : 0,
running : 0,
PERIOD : 1.3, PERIOD : 1.3,
last_time : 0.0, # For join handling. last_time : 0.0, # For join handling.
last_send : 0.0, # For the send queue last_send : 0.0, # For the send queue
@ -74,7 +134,8 @@ BroadcastChannel.new = func (mpp_path, process,
return obj; return obj;
} }
BroadcastChannel.send = func (msg) { BroadcastChannel.send = func (msg) {
if (me.send_node == nil) return; if (!me.running or me.send_node == nil)
return;
var t = getprop("/sim/time/elapsed-sec"); var t = getprop("/sim/time/elapsed-sec");
if (((t - me.last_send) > me.SEND_TIME) and (size(me.send_buf) == 0)) { if (((t - me.last_send) > me.SEND_TIME) and (size(me.send_buf) == 0)) {
@ -87,13 +148,21 @@ BroadcastChannel.send = func (msg) {
} }
BroadcastChannel.die = func { BroadcastChannel.die = func {
me.loopid += 1; me.loopid += 1;
me.running = 0;
# print("BroadcastChannel[" ~ me.mpp_path ~ "] ... destroyed."); # print("BroadcastChannel[" ~ me.mpp_path ~ "] ... destroyed.");
} }
BroadcastChannel.start = func { BroadcastChannel.start = func {
me.loopid += 1; if (!getprop("/sim/multiplay/online")) {
settimer(func { me._loop_(me.loopid); }, 0, 1); me.stop();
} else {
#print("mp_broadcast.nas: starting channel " ~ me.send_node.getPath() ~ ".");
me.running = 1;
me._loop_(me.loopid += 1);
}
} }
BroadcastChannel.stop = func { BroadcastChannel.stop = func {
#print("mp_broadcast.nas: stopping channel " ~ me.send_node.getPath() ~ ".");
me.running = 0;
me.loopid += 1; me.loopid += 1;
} }
@ -148,7 +217,10 @@ BroadcastChannel.update = func {
} }
} }
BroadcastChannel._loop_ = func (id) { BroadcastChannel._loop_ = func (id) {
me.running or return;
id == me.loopid or return; id == me.loopid or return;
#print("mp_broadcast.nas: " ~ me.send_node.getPath() ~ ":" ~ id ~ ".");
me.update(); me.update();
settimer(func { me._loop_(id); }, 0, 1); settimer(func { me._loop_(id); }, 0, 1);
} }
@ -159,6 +231,7 @@ BroadcastChannel._loop_ = func(id) {
# NOTE: MP is picky about what it sends in a string propery. # NOTE: MP is picky about what it sends in a string propery.
# Encode 7 bits as a printable 8 bit character. # Encode 7 bits as a printable 8 bit character.
var Binary = {}; var Binary = {};
Binary.TWOTO28 = 268435456;
Binary.TWOTO31 = 2147483648; Binary.TWOTO31 = 2147483648;
Binary.TWOTO32 = 4294967296; Binary.TWOTO32 = 4294967296;
Binary.sizeOf = {}; Binary.sizeOf = {};
@ -230,6 +303,21 @@ Binary.decodeCoord = func (str) {
Binary.decodeDouble(substr(str, 20))); Binary.decodeDouble(substr(str, 20)));
return coord; return coord;
} }
############################################################
# Encodes a string as a hash value.
Binary.sizeOf["Hash"] = 4;
Binary.stringHash = func (str) {
var hash = 0;
for(var i=0; i<size(str); i+=1) {
hash += math.mod(32*hash + str[i], Binary.TWOTO28-3);
}
return substr(Binary.encodeInt(hash), 1, 4);
}
############################################################
# Decodes an encoded geo.Coord object.
Binary.readHash = func (str) {
return substr(str, 0, Binary.sizeOf["Hash"]);
}
###################################################################### ######################################################################
############################################################################### ###############################################################################

62
Nasal/scenery.nas Normal file
View file

@ -0,0 +1,62 @@
###############################################################################
##
## Support tools for multiplayer enabled scenery objects.
##
## Copyright (C) 2011 Anders Gidenstam (anders(at)gidenstam.org)
## This file is licensed under the GPL license version 2 or later.
##
###############################################################################
# The event channel for scenery objects.
# See mp_broadcast.EventChannel for documentation.
var events = nil;
###############################################################################
# An extended aircraft.door that transmits the door events over MP using the
# scenery.events channel.
# Use only for single instance objects (e.g. static scenery objects).
#
# Note: Currently toggle() is the only shared event.
var sharedDoor = {
new: func(node, swingtime, pos = 0) {
var obj = aircraft.door.new(node, swingtime, pos);
obj.parents = [sharedDoor] ~ obj.parents;
obj.event_hash = mp_broadcast.Binary.stringHash
(isa(node, props.Node) ? node.getPath() : node);
events.register(obj.event_hash, func (msg) { obj._process(msg) });
return obj;
},
toggle: func {
events.send(me.event_hash, mp_broadcast.Binary.encodeByte(me.target));
me.move(me.target);
},
destroy : func {
events.deregister(me.event_hash);
},
_process : func (msg) {
me.target = mp_broadcast.Binary.decodeByte(msg);
me.move(me.target);
}
};
###############################################################################
# Internals
var shared_pp = "scenery/share-events";
_setlistener("sim/signals/nasal-dir-initialized", func {
events = mp_broadcast.EventChannel.new("scenery/events");
if (!getprop("/sim/multiplay/online") or !getprop(shared_pp)) {
#print("scenery.nas: stopping event sharing.");
events.stop();
}
setlistener(shared_pp, func (n) {
if (getprop("/sim/signals/reinit")) return; # Ignore resets.
if (n.getValue() and getprop("/sim/multiplay/online")) {
#print("scenery.nas: starting event sharing.");
events.start();
} else {
#print("scenery.nas: stopping event sharing.");
events.stop();
}
});
});

View file

@ -7,13 +7,17 @@ uniform float range; // From /sim/rendering/clouds3d-vis-range
attribute vec3 usrAttr1; attribute vec3 usrAttr1;
attribute vec3 usrAttr2; attribute vec3 usrAttr2;
attribute vec3 usrAttr3;
float textureIndexX = usrAttr1.r; float textureIndexX = usrAttr1.r;
float textureIndexY = usrAttr1.g; float textureIndexY = usrAttr1.g;
float wScale = usrAttr1.b; float wScale = usrAttr1.b;
float hScale = usrAttr2.r; float hScale = usrAttr2.r;
float shade = usrAttr2.g; float shade_factor = usrAttr2.g;
float cloud_height = usrAttr2.b; float cloud_height = usrAttr2.b;
float bottom_factor = usrAttr3.r;
float middle_factor = usrAttr3.g;
float top_factor = usrAttr3.b;
void main(void) void main(void)
{ {
@ -34,11 +38,12 @@ void main(void)
gl_Position.xyz = gl_Vertex.x * u; gl_Position.xyz = gl_Vertex.x * u;
gl_Position.xyz += gl_Vertex.y * r * wScale; gl_Position.xyz += gl_Vertex.y * r * wScale;
gl_Position.xyz += gl_Vertex.z * w * hScale; gl_Position.xyz += gl_Vertex.z * w * hScale;
gl_Position.xyz += gl_Color.xyz;
// Apply Z scaling to allow sprites to be squashed in the z-axis // Apply Z scaling to allow sprites to be squashed in the z-axis
gl_Position.z = gl_Position.z * gl_Color.w; gl_Position.z = gl_Position.z * gl_Color.w;
// Now shift the sprite to the correct position in the cloud.
gl_Position.xyz += gl_Color.xyz;
// Determine a lighting normal based on the vertex position from the // Determine a lighting normal based on the vertex position from the
// center of the cloud, so that sprite on the opposite side of the cloud to the sun are darker. // center of the cloud, so that sprite on the opposite side of the cloud to the sun are darker.
float n = dot(normalize(-gl_LightSource[0].position.xyz), float n = dot(normalize(-gl_LightSource[0].position.xyz),
@ -48,21 +53,29 @@ void main(void)
vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Position); vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Position);
float fogCoord = abs(ecPosition.z); float fogCoord = abs(ecPosition.z);
// Determine fractional height of vertex from 0 at the bottom, and 1 at mid-height. // Determine the shading of the vertex. We shade it based on it's position
// Used to determine shading. // in the cloud relative to the sun, and it's vertical position in the cloud.
float fract = smoothstep(0.0, cloud_height, gl_Position.z + cloud_height); float shade = mix(shade_factor, top_factor, smoothstep(-0.3, 0.0, n));
//if (n < 0) {
// shade = mix(top_factor, shade_factor, abs(n));
//}
float h = gl_Position.z;
shade = min(shade,
min(mix(bottom_factor, middle_factor, smoothstep(0.0, 0.5 * h, h)),
mix(middle_factor, top_factor, smoothstep(0.5 * h, h, h)) ) );
//float h = gl_Position.z / cloud_height;
//if (h < 0.5) {
// shade = min(shade, mix(bottom_factor, middle_factor, smoothstep(0.0, 0.5, h)));
//} else {
// shade = min(shade, mix(middle_factor, top_factor, smoothstep(2.0 * (h - 0.5)));
// }
// Final position of the sprite // Final position of the sprite
gl_Position = gl_ModelViewProjectionMatrix * gl_Position; gl_Position = gl_ModelViewProjectionMatrix * gl_Position;
// Determine the shading of the sprite based on its vertical position and position relative to the sun. gl_FrontColor = gl_LightSource[0].diffuse * shade + gl_FrontLightModelProduct.sceneColor;
n = min(smoothstep(-0.5, 0.0, n), fract);
// Determine the shading based on a mixture from the backlight to the front
vec4 backlight = gl_LightSource[0].diffuse * shade;
gl_FrontColor = mix(backlight, gl_LightSource[0].diffuse, n);
gl_FrontColor += gl_FrontLightModelProduct.sceneColor;
// As we get within 100m of the sprite, it is faded out. Equally at large distances it also fades out. // As we get within 100m of the sprite, it is faded out. Equally at large distances it also fades out.
gl_FrontColor.a = min(smoothstep(10.0, 100.0, fogCoord), 1.0 - smoothstep(range*0.8, range, fogCoord)); gl_FrontColor.a = min(smoothstep(10.0, 100.0, fogCoord), 1.0 - smoothstep(range*0.8, range, fogCoord));

View file

@ -2,18 +2,23 @@
// http://www.bonzaisoftware.com/water_tut.html and its glsl conversion // http://www.bonzaisoftware.com/water_tut.html and its glsl conversion
// available at http://forum.bonzaisoftware.com/viewthread.php?tid=10 // available at http://forum.bonzaisoftware.com/viewthread.php?tid=10
// © Michael Horsch - 2005 // © Michael Horsch - 2005
// Major update and revisions - 2011-10-07
// © Emilian Huminiuc and Vivian Meazza
#version 120 #version 120
#pragma debug(on)
uniform sampler2D water_normalmap; uniform sampler2D water_normalmap;
uniform sampler2D water_reflection; uniform sampler2D water_reflection;
uniform sampler2D water_dudvmap; uniform sampler2D water_dudvmap;
uniform sampler2D water_reflection_grey; uniform sampler2D water_reflection_grey;
uniform sampler2D sea_foam; uniform sampler2D sea_foam;
uniform sampler2D perlin_normalmap;
uniform sampler3D Noise;
uniform float saturation, Overcast, WindE, WindN; uniform float saturation, Overcast, WindE, WindN;
uniform float CloudCover0, CloudCover1, CloudCover2, CloudCover3, CloudCover4; uniform float CloudCover0, CloudCover1, CloudCover2, CloudCover3, CloudCover4;
uniform float osg_SimulationTime;
uniform int Status; uniform int Status;
varying vec4 waterTex1; //moving texcoords varying vec4 waterTex1; //moving texcoords
@ -24,12 +29,23 @@ varying vec3 viewerdir;
varying vec3 lightdir; varying vec3 lightdir;
varying vec3 normal; varying vec3 normal;
/////// functions /////////
void rotationmatrix(in float angle, out mat4 rotmat)
{
rotmat = mat4( cos( angle ), -sin( angle ), 0.0, 0.0,
sin( angle ), cos( angle ), 0.0, 0.0,
0.0 , 0.0 , 1.0, 0.0,
0.0 , 0.0 , 0.0, 1.0 );
}
void main(void) void main(void)
{ {
const vec4 sca = vec4(0.005, 0.005, 0.005, 0.005); const vec4 sca = vec4(0.005, 0.005, 0.005, 0.005);
const vec4 sca2 = vec4(0.02, 0.02, 0.02, 0.02); const vec4 sca2 = vec4(0.02, 0.02, 0.02, 0.02);
const vec4 tscale = vec4(0.25, 0.25, 0.25, 0.25); const vec4 tscale = vec4(0.25, 0.25, 0.25, 0.25);
mat4 RotationMatrix;
// compute direction to viewer // compute direction to viewer
vec3 E = normalize(viewerdir); vec3 E = normalize(viewerdir);
@ -39,40 +55,55 @@ void main(void)
// half vector // half vector
vec3 H = normalize(L + E); vec3 H = normalize(L + E);
const float water_shininess = 240.0; vec3 Normal = normalize(normal);
// calculate wind effects const float water_shininess = 240.0;
float windEffect = sqrt(pow(abs(WindE),2)+pow(abs(WindN),2)) * 0.6;
float windScale = 10.0/(6.0 + 8.0 * smoothstep(0.0,0.8,windEffect * 0.05));
// approximate cloud cover // approximate cloud cover
float cover = 0.0; float cover = 0.0;
//bool Status = true; //bool Status = true;
float windEffect = sqrt(pow(abs(WindE),2)+pow(abs(WindN),2)) * 0.6; //wind speed in kt
float windScale = 15.0/(3.0 + windEffect); //wave scale
float windEffect_low = 0.4 + 0.6 * smoothstep(0.0, 5.0, windEffect); //low windspeed wave filter
float waveRoughness = 0.15 + smoothstep(0.0, 15.0, windEffect); //wave roughness filter
//float noise_factor = 0.2 + 0.15 * smoothstep(0.0, 40.0, windEffect);
if (Status == 1){ if (Status == 1){
cover = min(min(min(min(CloudCover0, CloudCover1),CloudCover2),CloudCover3),CloudCover4); cover = min(min(min(min(CloudCover0, CloudCover1),CloudCover2),CloudCover3),CloudCover4);
} else { } else {
// hack to allow for Overcast not to be set by Local Weather // hack to allow for Overcast not to be set by Local Weather
if (Overcast == 0){ if (Overcast == 0){
cover = 5; cover = 5;
} else { } else {
cover = Overcast * 5; cover = Overcast * 5;
} }
} }
vec4 viewt = normalize(waterTex4); vec4 viewt = normalize(waterTex4);
vec4 disdis = texture2D(water_dudvmap, vec2(waterTex2 * tscale)* windScale) * 2.0 - 1.0; vec4 disdis = texture2D(water_dudvmap, vec2(waterTex2 * tscale)* windScale) * 2.0 - 1.0;
vec4 dist = texture2D(water_dudvmap, vec2(waterTex1 + disdis*sca2)* windScale) * 2.0 - 1.0; vec4 dist = texture2D(water_dudvmap, vec2(waterTex1 + disdis*sca2)* windScale) * 2.0 - 1.0;
dist *= (0.6 + 0.5 * smoothstep(0.0, 15.0, windEffect));
vec4 fdist = normalize(dist); vec4 fdist = normalize(dist);
fdist = -fdist; //dds fix
fdist *= sca; fdist *= sca;
//normalmap //normalmaps
vec4 nmap0 = texture2D(water_normalmap, vec2(waterTex1+ disdis*sca2) * windScale) * 2.0 - 1.0; vec4 nmap = texture2D(water_normalmap, vec2(waterTex1 + disdis * sca2) * windScale) * 2.0 - 1.0;
vec4 nmap2 = texture2D(water_normalmap, vec2(waterTex2 * tscale) * windScale) * 2.0 - 1.0; vec4 nmap1 = texture2D(perlin_normalmap, vec2(waterTex1 + disdis * sca2) * windScale) * 2.0 - 1.0;
vec4 vNorm = normalize(nmap0 + nmap2);
rotationmatrix(radians(3.0 * sin(osg_SimulationTime * 0.0075)), RotationMatrix);
nmap += texture2D(water_normalmap, vec2(waterTex2 * RotationMatrix * tscale) * windScale) * 2.0 - 1.0;
nmap1 += texture2D(perlin_normalmap, vec2(waterTex2 * RotationMatrix * tscale) * windScale) * 2.0 - 1.0;
nmap *= windEffect_low;
nmap1 *= windEffect_low;
// mix water and noise, modulated by factor
vec4 vNorm = normalize(mix(nmap, nmap1, 0.3) * waveRoughness);
vNorm = -vNorm; //dds fix
//load reflection //load reflection
vec4 tmp = vec4(lightdir, 0.0); vec4 tmp = vec4(lightdir, 0.0);
@ -93,15 +124,31 @@ void main(void)
} }
vec3 N0 = vec3(texture2D(water_normalmap, vec2(waterTex1 + disdis * sca2) * windScale) * 2.0 - 1.0); vec3 N0 = vec3(texture2D(water_normalmap, vec2(waterTex1 + disdis * sca2) * windScale) * 2.0 - 1.0);
vec3 N1 = vec3(texture2D(water_normalmap, vec2(waterTex2 * tscale) * windScale) * 2.0 - 1.0); vec3 N1 = vec3(texture2D(perlin_normalmap, vec2(waterTex1 + disdis * sca) * windScale) * 2.0 - 1.0);
vec3 N = normalize(normal+N0+N1);
N0 += vec3(texture2D(water_normalmap, vec2(waterTex2 * tscale) * windScale) * 2.0 - 1.0);
N1 += vec3(texture2D(perlin_normalmap, vec2(waterTex2 * tscale) * windScale) * 2.0 - 1.0);
rotationmatrix(radians(2.0 * sin(osg_SimulationTime * 0.005)), RotationMatrix);
N0 += vec3(texture2D(water_normalmap, vec2(waterTex2 * RotationMatrix * (tscale + sca2)) * windScale) * 2.0 - 1.0);
N1 += vec3(texture2D(perlin_normalmap, vec2(waterTex2 * RotationMatrix * (tscale + sca2)) * windScale) * 2.0 - 1.0);
rotationmatrix(radians(-4.0 * sin(osg_SimulationTime * 0.003)), RotationMatrix);
N0 += vec3(texture2D(water_normalmap, vec2(waterTex1 * RotationMatrix + disdis * sca2) * windScale) * 2.0 - 1.0);
N1 += vec3(texture2D(perlin_normalmap, vec2(waterTex1 * RotationMatrix + disdis * sca) * windScale) * 2.0 - 1.0);
N0 *= windEffect_low;
N1 *= windEffect_low;
vec3 N = normalize(mix(Normal + N0 , Normal + N1, 0.3) * waveRoughness);
N = -N; //dds fix
// specular // specular
vec3 specular_color = vec3(gl_LightSource[0].diffuse) vec3 specular_color = vec3(gl_LightSource[0].diffuse)
* pow(max(0.0, dot(N, H)), water_shininess) * 6.0; * pow(max(0.0, dot(N, H)), water_shininess) * 6.0;
vec4 specular = vec4(specular_color, 0.5); vec4 specular = vec4(specular_color, 0.5);
specular = specular * saturation * 0.4; specular = specular * saturation * 0.3 ;
//calculate fresnel //calculate fresnel
vec4 invfres = vec4( dot(vNorm, viewt) ); vec4 invfres = vec4( dot(vNorm, viewt) );
@ -121,25 +168,20 @@ void main(void)
vec4 ambient_light = gl_LightSource[0].diffuse; vec4 ambient_light = gl_LightSource[0].diffuse;
vec4 finalColor; vec4 finalColor;
// cover = 0;
if(cover >= 1.5){ if(cover >= 1.5){
finalColor = refl + specular; finalColor = refl + specular;
} else { } else {
finalColor = refl; finalColor = refl;
} }
if (windEffect >= 10.0){ float foamSlope = 0.1 + 0.1 * windScale;
float windScale3 = pow(windScale, 3); if (windEffect >= 10.0)
if (N.g >= foamSlope){
if (N.g >= 0.0005 + 0.085 * windScale3){ vec4 foam_texel = texture2D(sea_foam, vec2(waterTex2 * tscale) * 30.0);
vec4 foam_texel = texture2D(sea_foam, vec2(waterTex1+ disdis*sca2) * windScale3 * 50.0); finalColor = mix(finalColor, max(finalColor, finalColor + foam_texel), smoothstep(foamSlope, 0.25, N.g));
finalColor = mix(finalColor, max(finalColor, foam_texel), smoothstep(0.0005 + 0.085 * windScale3, 0.1, N.g));
} }
}
finalColor *= ambient_light; finalColor *= ambient_light;
gl_FragColor = mix(gl_Fog.color, finalColor, fogFactor); gl_FragColor = mix(gl_Fog.color, finalColor, fogFactor);
} }

View file

@ -2,6 +2,8 @@
// http://www.bonzaisoftware.com/water_tut.html and its glsl conversion // http://www.bonzaisoftware.com/water_tut.html and its glsl conversion
// available at http://forum.bonzaisoftware.com/viewthread.php?tid=10 // available at http://forum.bonzaisoftware.com/viewthread.php?tid=10
// © Michael Horsch - 2005 // © Michael Horsch - 2005
// Major update and revisions - 2011-10-07
// © Emilian Huminiuc and Vivian Meazza
#version 120 #version 120
@ -9,14 +11,27 @@ varying vec4 waterTex1;
varying vec4 waterTex2; varying vec4 waterTex2;
varying vec4 waterTex4; varying vec4 waterTex4;
varying vec4 ecPosition; varying vec4 ecPosition;
uniform float osg_SimulationTime;
uniform float WindE, WindN;
varying vec3 viewerdir; varying vec3 viewerdir;
varying vec3 lightdir; varying vec3 lightdir;
varying vec3 normal; varying vec3 normal;
uniform float osg_SimulationTime;
uniform float WindE, WindN;
/////// functions /////////
void rotationmatrix(in float angle, out mat4 rotmat)
{
rotmat = mat4( cos( angle ), -sin( angle ), 0.0, 0.0,
sin( angle ), cos( angle ), 0.0, 0.0,
0.0 , 0.0 , 1.0, 0.0,
0.0 , 0.0 , 0.0, 1.0 );
}
void main(void) void main(void)
{ {
mat4 RotationMatrix;
vec3 N = normalize(gl_Normal); vec3 N = normalize(gl_Normal);
normal = N; normal = N;
@ -30,15 +45,14 @@ waterTex4 = vec4( ecPosition.xzy, 0.0 );
vec4 t1 = vec4(0.0, osg_SimulationTime * 0.005217, 0.0, 0.0); vec4 t1 = vec4(0.0, osg_SimulationTime * 0.005217, 0.0, 0.0);
vec4 t2 = vec4(0.0, osg_SimulationTime * -0.0012, 0.0, 0.0); vec4 t2 = vec4(0.0, osg_SimulationTime * -0.0012, 0.0, 0.0);
//float windFactor = sqrt(pow(abs(WindE),2)+pow(abs(WindN),2)) * 0.3; float windFactor = sqrt(pow(abs(WindE),2)+pow(abs(WindN),2)) * 0.01;
float windFactor = 0.001; float Angle = atan(-WindN + 0.001, WindE + 0.001) - atan(1.0);
waterTex1 = gl_MultiTexCoord0 + t1; rotationmatrix(Angle, RotationMatrix);
waterTex1.x += WindE * windFactor; waterTex1 = gl_MultiTexCoord0 * RotationMatrix - t1 * windFactor;
waterTex1.y += WindN * windFactor;
waterTex2 = gl_MultiTexCoord0 + t2; rotationmatrix(Angle, RotationMatrix);
waterTex2.x += WindE * windFactor; waterTex2 = gl_MultiTexCoord0 * RotationMatrix - t2 * windFactor;
waterTex2.y += WindN * windFactor;
gl_Position = ftransform(); gl_Position = ftransform();
} }

Binary file not shown.

BIN
Textures/Water/sea_foam.dds Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Textures/Water/waves2.dds Normal file

Binary file not shown.

View file

@ -1273,6 +1273,11 @@ Started September 2000 by David Megginson, david@megginson.com
</jetways_edit> </jetways_edit>
</nasal> </nasal>
<scenery>
<share-events type="bool" userarchive="y">false</share-events>
<events type="string"/>
</scenery>
</PropertyList> </PropertyList>
<!-- end of preferences.xml --> <!-- end of preferences.xml -->