FSXA Several objects showing one by one

#1
I have several objects textured with different textures. What I need to achive is to show them up one by one, in concescutive way, all of them within one second. To do this I need to set L:Timer once a second so my question is: if "Update" can be used in modeldef.xml and how OR is there any other way to establish such "logic" which will set local timer and reset it every second.

I will appreciate any help.

Radek Koterbski
vel IntruderPL
 
#2
I'm trying to write propper code for the task in modeldef.xml. I didn't check it but perhaps someone would find an errors to improve it.

Code:
	<PartInfo>
		<Name>AN28_Timer_logic</Name>
		<Visibility>
			<Parameter>
					<Code>
						(E:LOCAL TIME, seconds) (>L:TimerX, enum)
						(L:ResetTimerX, bool) 1 &lt;
						and
						if{ 1 } els { 0 }
					</Code>
			</Parameter>
		</Visibility>
	</PartInfo>

	<PartInfo>
		<Name>AN28_Timer_logic_2</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:TimerX, enum) 0.25 + (E:LOCAL TIME, seconds) <=; if{ 1 (>L:Tex01, enum) } els { 0 (>L:Tex01, enum) }																	// If the value of (E:Local Time) is lower or equal (L:TimerX + 0.25sec) write 1 into (L:Tex01) else write 0 into (L:Tex01)
					(L:TimerX, enum) 0.25 + (E:LOCAL TIME, seconds) &gt; (L:TimerX, enum) 0.50 + (E:LOCAL TIME, seconds) <=; AND; if{ 1 (>L:Tex02, enum) } els { 0 (>L:Tex02, enum) }		// If the value of (E:Local Time) is greater then (L:TimerX + 0.25) AND the value is lower or equal (L:TimerX + 0.50) write 1 into (L:Tex01) else write 0 into (L:Tex01)
					(L:TimerX, enum) 0.50 + (E:LOCAL TIME, seconds) &gt; (L:TimerX, enum) 0.75 + (E:LOCAL TIME, seconds) <=; AND; if{ 1 (>L:Tex03, enum) } els { 0 (>L:Tex03, enum) }		// and so on
					(L:TimerX, enum) 0.75 + (E:LOCAL TIME, seconds) &gt; (L:TimerX, enum) 1 + (E:LOCAL TIME, seconds) &lt; AND; if{ 1 (>L:Tex04, enum) } els { 0 (>L:Tex04, enum) }			// ...
					(L:TimerX, enum) 1 + (E:LOCAL TIME, seconds) ==; if{ 1 (>L:ResetTimerX, bool) } els { 0 (>L:ResetTimerX, bool) }														// If the value of (E:Local Time) is equal to (L:TimerX + 1 sec) activate (L:ResetTimerX) to make another cycle
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>	
	
	
	<PartInfo>
		<Name>AN28_Tex01</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:CONDITION_01, enum) 0 &gt;
					(L:Tex01, enum) 1 ==;
					and
					if{ 1 } els{ 0 }
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>
IntruderPL
 
#3
VC rain effect

To clarify things I should add that the code is all about rain effect on VC windsheld.

Another try, as below:

Code:
<!-- An28 custom rain effect on windsheld.  -->	

<!-- Timer_Init checks if InitTimerX is FALSE. If YES, it write TRUE both into L:ResetTimerX (which starts Timer_logic code by itself) and  L:InitTimerX--> 
<!-- The code run once because of InitTimerX which is FALSE only once, at the very beginning -->	

	<PartInfo>
		<Name>AN28_Timer_Init</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:InitTimerX, bool) 0 ==
					if{ 1 (>L:ResetTimerX, bool) 1 (>L:InitTimerX, bool) }
					els{ 0 }
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>	
	
<!-- Code store a new value into TimerX every time the ResetTimerX is TRUE. The code starts when the Timer_Init_3 has been initialized -->
<!-- and then will repeat every time the Timer_logic_2 run its last condition -->

	<PartInfo>
		<Name>AN28_Timer_logic</Name>
		<Visibility>
			<Parameter>
					<Code>
						(L:ResetTimerX, bool) 1 ==
						if{ (E:LOCAL TIME, seconds) (>L:TimerX, enum) } 
						els{ 0 }
					</Code>
			</Parameter>
		</Visibility>
	</PartInfo>

<!-- Code checks if TimerX has a value stored. If yes, the code checks timing and write TRUE into several LVars respectively -->	
	
	<PartInfo>
		<Name>AN28_Timer_Checking</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:TimerX, enum) 0 &gt;
					if{ 
					(L:TimerX, enum) 0.25 + (E:LOCAL TIME, seconds) &lt; if{ 1 (>L:Tex01, enum) } els { 0 (>L:Tex01, enum) }																
					(L:TimerX, enum) 0.25 + (E:LOCAL TIME, seconds) &gt; (L:TimerX, enum) 0.50 + (E:LOCAL TIME, seconds) &lt; and if{ 1 (>L:Tex02, enum) } els { 0 (>L:Tex02, enum) }
					or	
					(L:TimerX, enum) 0.50 + (E:LOCAL TIME, seconds) &gt; (L:TimerX, enum) 0.75 + (E:LOCAL TIME, seconds) &lt; and if{ 1 (>L:Tex03, enum) } els { 0 (>L:Tex03, enum) }
					or
					(L:TimerX, enum) 0.75 + (E:LOCAL TIME, seconds) &gt; (L:TimerX, enum) 1 + (E:LOCAL TIME, seconds) &lt; and if{ 1 (>L:Tex04, enum) } els { 0 (>L:Tex04, enum) }	
					or
					(L:TimerX, enum) 1 + (E:LOCAL TIME, seconds) == if{ 1 (>L:ResetTimerX, bool) } els { 0 (>L:ResetTimerX, bool) }
					or 
					}
					els{ 0 }
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>	

<!-- Code checks if it's rainning and LTex01 has stored value equal 1. The object will show up based on both "TRUE" condition -->
	
	<PartInfo>
		<Name>AN28_Tex01</Name>
		<Visibility>
			<Parameter>
				<Code>
					(A:AMBIENT PRECIP STATE, number) 4 ==
					(L:Tex01, enum) 1 ==
					and
					if{ 1 } els{ 0 }
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>
It dosn't work at all. I don't have a clue why...
Help? :(

Greetings
IntruderPL

EIDT: New version of code posted, some minor errors have been fixed (ie. semicolons at an ends of a few expressions).
 
Last edited:
#5
I wish I had the answer.
The same on my side as I'm looking for it whole day :) Perhaps there is some syntax error I can't notice. The XML is still a mystery for me.

At least, with the next version od code (below) the first object has showed up based on weather condition. By the first object I mean a copy of cockpit window textured with rain material. Unfortunately, the objects don't change so far, so the problem still exists somewhere within the "Timer"Checking" part, I think.

Code:
<!-- An28 custom rain effect on windsheld.  -->	

<!-- Timer_Init checks if InitTimerX is FALSE. If YES, it write TRUE both into L:ResetTimerX (which starts Timer_logic code by itself) and  L:InitTimerX--> 
<!-- The code run once because of InitTimerX which is FALSE only once, at the very beginning -->	

	<PartInfo>
		<Name>AN28_Timer_Init</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:InitTimerX, bool) 0 ==
					if{ 1 (>L:ResetTimerX, bool) 1 (>L:InitTimerX, bool) }
					els{ 0 }
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>	
	
<!-- Code store a new value into TimerX every time the ResetTimerX is TRUE. The code starts when the Timer_Init_3 has been initialized -->
<!-- and then will repeat every time the Timer_logic_2 run its last condition -->

	<PartInfo>
		<Name>AN28_Timer_logic</Name>
		<Visibility>
			<Parameter>
					<Code>
						(L:ResetTimerX, bool) 1 ==
						if{ (E:LOCAL TIME, seconds) (>L:TimerX, enum) } 
						els{ 0 }
					</Code>
			</Parameter>
		</Visibility>
	</PartInfo>

<!-- Code checks if TimerX has a value stored. If yes, the code checks timing and write TRUE into several LVars respectively -->	
<!-- Code:     	if ( (L:value) > 10 ) { return (L:value) } else { return 10 }     -->	
<!-- Gives:		(L:value) 10 > if{ (L:value) } els{ 10 }     -->
	
	
	
	<PartInfo>
		<Name>AN28_Timer_Checking</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:TimerX, enum) 0 &gt;
					if{ 
					(L:TimerX, enum) 0.25 + (E:LOCAL TIME, seconds) &lt; if{ 1 (>L:Tex01, enum) } els{ 0 (>L:Tex01, enum) };																
					(L:TimerX, enum) 0.25 + (E:LOCAL TIME, seconds) &gt; (L:TimerX, enum) 0.50 + (E:LOCAL TIME, seconds) &lt; and if{ 1 (>L:Tex02, enum) } els{ 0 (>L:Tex02, enum) };	
					(L:TimerX, enum) 0.50 + (E:LOCAL TIME, seconds) &gt; (L:TimerX, enum) 0.75 + (E:LOCAL TIME, seconds) &lt; and if{ 1 (>L:Tex03, enum) } els{ 0 (>L:Tex03, enum) };
					(L:TimerX, enum) 0.75 + (E:LOCAL TIME, seconds) &gt; (L:TimerX, enum) 1 + (E:LOCAL TIME, seconds) &lt; and if{ 1 (>L:Tex04, enum) } els{ 0 (>L:Tex04, enum) };	
					(L:TimerX, enum) 1 + (E:LOCAL TIME, seconds) == if{ 1 (>L:ResetTimerX, bool) } els{ 0 (>L:ResetTimerX, bool) };
					or
					or
					or
					or
					}
					els{ 0 }
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>	

<!-- Code checks if it's rainning and LTex01 has stored value equal 1. The object will show up based on both "TRUE" conditions -->
	
	<PartInfo>
		<Name>AN28_Tex01</Name>
		<Visibility>
			<Parameter>
				<Code>
					(A:AMBIENT PRECIP STATE, number) 4 ==
					(L:Tex01, enum) 1 ==
					and
					if{ 1 } els{ 0 }
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>


Intruder
 
Last edited:

tgibson

Resource contributor
#6
I don't know if you can do that or not.

My approach would be to create an invisible panel gauge that set the value of an L: variable that varied with time. Then each object would appear in the model when the L: variable equaled a certain value.

Hope this helps,
 
#7
Thanks Tom! Well, I wanted to avoid making of 2D gauge since I havn't got any in my project. Even I dispersed the timer-checking code into object's part but still NO-GO. The outcome is the same as previous = only the first "rainy" object is visible. Note that only the first object's code is posted. The code is expandable just only by cloning more objects (and their code) and adjusting timing respectively. Also it can be used to show other weather effects like icing for example. The only thing we need is the working code :)

Code:
<!-- An28 custom rain effect on windsheld.  -->	


	<PartInfo>
		<Name>AN28_Timer_Init</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:InitTimerX, bool) 0 ==
					if{ 1 (>L:ResetTimerX, bool) 1 (>L:InitTimerX, bool) }
					els{ 0 }
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>	
	

	<PartInfo>
		<Name>AN28_Timer_logic</Name>
		<Visibility>
			<Parameter>
					<Code>
						(L:ResetTimerX, bool) 1 ==
						if{ (E:LOCAL TIME, seconds) (>L:TimerX, enum) } 
						els{ 0 }
					</Code>
			</Parameter>
		</Visibility>
	</PartInfo>


	<PartInfo>
		<Name>AN28_Timer_Checking</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:TimerX, enum) 1 + (E:LOCAL TIME, seconds) == 
						if{ 1 (>L:ResetTimerX, bool) } 
						els{ 0 (>L:ResetTimerX, bool) }
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>	

		
	<PartInfo>
		<Name>AN28_Tex01</Name>
		<Visibility>
			<Parameter>
				<Code>
					(A:AMBIENT PRECIP STATE, number) 4 ==
					(L:TimerX, enum) 0.25 + (E:LOCAL TIME, seconds) &lt;
					and
					if{ 1 } els{ 0 }
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>
Intruder
 
Last edited:

n4gix

Resource contributor
#8
Thanks Tom! Well, I wanted to avoid making of 2D gauge since I havn't got any in my project.
Two methods present themselves as working solutions.

First of all, all of your "control logic" should be in one, and only one location. For a 3d model, the simplest method is to create one tiny polygon in a hidden location in your model (0,0,0) and facing down is easiest.

To this single polygon, attach a <Visibility> script in which all of your "control logic" has been placed. This functions identically to an <Update> section in a 2d XML gauge.

Code:
   <PartInfo>
    <Name>T38_Logic</Name>
    <Visibility>
      <Parameter>
        <Code>
          <!-- INITIALIZATION ROUTINE(S) -->
          (L:T38_Init,bool) 0 ==
          if{
	   1 (>L:T38_AntennaSelect, enum)
	   1 (>L:T38_CompassGyro, enum)
	     <!-- SET ALL CONSTANT INIT VALUES -->
			
	   1 (>L:T38_Logic,bool)
	 }
			
          <!-- 1 SECOND UPDATE -->
          (P:Absolute time,seconds) 1 % 1 > !
          if{
          
	     <!-- PLACE ALL LOGIC SCRIPTS HERE -->
			
	   }
        </Code>
      </Parameter>
    </Visibility>
  </PartInfo>
The reason for this is simple. If you have your "control logic" scattered among multiple parts, you have absolutely NO CONTROL over the order in which those logic statements will be executed! XML is executed from the top of the script to the bottom, then repeats this top-to-bottom loop as long as the aircraft is loaded.

The second method is the one I use most often, which is to create a single [VCockpit00] section in the panel.cfg file, and place an XML "logic gauge" there while developing and testing. This will allow you to make quick changes and test the changes without having to constantly revise the modeldef.xml file and recompile the entire aircraft!!! :D

Then, once your "control logic" is fully debugged and tested, simply copy/paste the completed XML script into the aforementioned <Visibility> section as described above.
 

n4gix

Resource contributor
#10
Big thanks Bill! It is exactly what I was looking for :) I will try to adapt the code to my needs.
One question:


What does it exactly mean Bill?

Intruder
It is a timer that will limit all the script within the { } curly braces to executing only once per second.

<!--
With this universal code it's very simple to control not only the length of the cycle but the frequency of the
blink itself:
Pseudocode:<Visble>(P:Absolute time,seconds) "seed" % "blink lapse" > !</Visible>
The seed parameter is the total length of the blinking cycle. For example, if you want something to blink on every
second, you use 1, if you want it blink every half a second, use 0.5 , every two seconds, 2 ,etc.

For each seed, you can determine how long would be the duration of both the visible and invisible part.
Then:
Code:
(P:Absolute time,seconds) 1 % 0.5 > !
this will make the visible and invisible parts of half a second both.

Code:
(P:Absolute time,seconds) 1 % 0.7 > !
this will make the visible part 70% of the cycle (0.7 secs) and invisible parts of 30 % (0.3 secs).

Code:
(P:Absolute time,seconds) 0.5 % 0.25 > !
this will make the visible and invisible parts a quarter of second both.
You can invert the cycle by removing the "!" char.
-->
 
#11
Eh...
After many tries only one object (don't know which one of these four) flashes with frequency 0.5 sec on 0.5 sec. Still no-go...
Whole code below.

Code:
<!-- An28 custom rain effect on windsheld.  -->	

   <PartInfo>
    <Name>AN28_RainLogic</Name>
    <Visibility>
      <Parameter>
        <Code>
          <!-- ROUTINE IS INITIALIZED BY RAIN -->
		(A:AMBIENT PRECIP STATE, number) 4 ==
			if{ 1 (>L:TimerInitX,bool) }
			els{ 0 (>L:TimerInitX,bool) }
			
          <!-- 1 SECOND UPDATE -->
		(P:Absolute time,seconds) 1 % 0.3 > !
			if{ 
				(E:LOCAL TIME, seconds) (>L:TimerX, seconds) 
			}

	 <!-- CHECKING TIMING WHEN RAINING -->
			(L:TimerInitX,bool) 1 ==
			if{ 
				(L:TimerX, seconds) 0.25 + (E:LOCAL TIME, seconds) &lt; 
					if{ 1 (>L:Tex01, enum) } els{ 0 (>L:Tex01, enum) }
				(L:TimerX, seconds) 0.25 + (E:LOCAL TIME, seconds) &gt; 
				(L:TimerX, seconds) 0.50 + (E:LOCAL TIME, seconds) &lt; 
				and
					if{ 1 (>L:Tex02, enum) } els{ 0 (>L:Tex02, enum) } 
				(L:TimerX, seconds) 0.50 + (E:LOCAL TIME, seconds) &gt; 
				(L:TimerX, seconds) 0.75 + (E:LOCAL TIME, seconds) &lt; 
				and 
					if{ 1 (>L:Tex03, enum) } els{ 0 (>L:Tex03, enum) }
				(L:TimerX, seconds) 0.75 + (E:LOCAL TIME, seconds) &gt; 
				(L:TimerX, seconds) 1 + (E:LOCAL TIME, seconds) &lt; 
				and 
					if{ 1 (>L:Tex04, enum) } els{ 0 (>L:Tex04, enum) } 
			}
        </Code>
      </Parameter>
    </Visibility>
  </PartInfo>



	<PartInfo>
		<Name>AN28_Tex01</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex01, enum) 1 ==
					if{ 1 } els{ 0 }
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>

	<PartInfo>
		<Name>AN28_Tex02</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex02, enum) 1 ==
					if{ 1 } els{ 0 }
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>

	<PartInfo>
		<Name>AN28_Tex03</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex03, enum) 1 ==
					if{ 1 } els{ 0 }
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>

	<PartInfo>
		<Name>AN28_Tex04</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex04, enum) 1 ==
					if{ 1 } els{ 0 }
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>
Intruder
 
#13
I don't understand the idea of a timer apperently...
This two (below) causes only one rain texture to be shown permanently instead of showing of the four textures in sequence, one by one.

Code:
          <!-- 1 SECOND UPDATE -->
		(P:Absolute time,seconds) 1 % 1 > !
			if{ 
				(E:LOCAL TIME, seconds) (>L:TimerX, seconds);
				(L:TimerX, seconds) 0.25 + (E:LOCAL TIME, seconds) &lt; 
					if{ 1 (>L:Tex01, enum) } els{ 0 (>L:Tex01, enum) }
				(L:TimerX, seconds) 0.25 + (E:LOCAL TIME, seconds) &gt; 
				(L:TimerX, seconds) 0.50 + (E:LOCAL TIME, seconds) &lt; 
				and
					if{ 1 (>L:Tex02, enum) } els{ 0 (>L:Tex02, enum) } 
				(L:TimerX, seconds) 0.50 + (E:LOCAL TIME, seconds) &gt; 
				(L:TimerX, seconds) 0.75 + (E:LOCAL TIME, seconds) &lt; 
				and 
					if{ 1 (>L:Tex03, enum) } els{ 0 (>L:Tex03, enum) }
				(L:TimerX, seconds) 0.75 + (E:LOCAL TIME, seconds) &gt; 
				(L:TimerX, seconds) 1 + (E:LOCAL TIME, seconds) &lt; 
				and 
					if{ 1 (>L:Tex04, enum) } els{ 0 (>L:Tex04, enum) } 
			}

and this one

Code:
         <!-- 1 SECOND UPDATE -->
		(P:Absolute time,seconds) 1 % 1 > !
			if{ 
				(L:Absolute time, seconds) 0.25 + &lt; 
					if{ 1 (>L:Tex01, enum) } els{ 0 (>L:Tex01, enum) }
				(L:Absolute time, seconds) 0.25 + &gt; 
				(L:Absolute time, seconds) 0.50 + &lt; 
				and
					if{ 1 (>L:Tex02, enum) } els{ 0 (>L:Tex02, enum) } 
				(L:Absolute time, seconds) 0.50 + &gt; 
				(L:Absolute time, seconds) 0.75 + &lt; 
				and 
					if{ 1 (>L:Tex03, enum) } els{ 0 (>L:Tex03, enum) }
				(L:Absolute time, seconds) 0.75 + &gt; 
				(L:Absolute time, seconds) 1 + &lt; 
				and 
					if{ 1 (>L:Tex04, enum) } els{ 0 (>L:Tex04, enum) } 
			}

Intruder
 

n4gix

Resource contributor
#14
It's really quite simple, but a bit difficult to explain in words...

You create one timer, then have the textures display in sequence, then loop back to the beginning. They will continue to loop until you tell it to stop. This timer will "fire" every 1/4th second. Oh, you probably would want to expand the texture loop to 18, to match the FS9 sequence.
Code:
(P:Absolute time,seconds) 0.25 % 0.25 > !
if{
     (L:vc_rain,enum) ++ (>L:vc_rain,enum) /* LOOP COUNTER */

     (L:vc_rain,enum) 0 == if{ 1 (>L:Tex01,enum) 0 (>L:Tex04,enum) } /* DISPLAY 1st TEXTURE, HIDE PREVIOUS TEXTURE */
     (L:vc_rain,enum) 1 == if{ 1 (>L:Tex02,enum) 0 (>L:Tex01,enum) }
     (L:vc_rain,enum) 2 == if{ 1 (>L:Tex03,enum) 0 (>L:Tex02,enum) }
     (L:vc_rain,enum) 3 == if{ 1 (>L:Tex04,enum) 0 (>L:Tex03,enum) }
     (L:vc_rain,enum) 4 == if{ 0 (>L:vc_rain,enum) } /* THIS RESETS THE LOOP COUNTER */
}
 
Last edited:
#15
Was that so simple? I've never been even close to THIS way to solve the issue. And you are right Bill, as always :) I'm gonna expand the code to match my sequence of texture (possible 18/sec but it will depends on performance).

THANK YOU VERY MUCH BILL! :)
 

n4gix

Resource contributor
#16
HINT: You don't even need to create custom textures. You could simply use the one's that MS/ACES provided for FS9, or the ones that Joe Binka did as improved versions: vcrain.zip available at AVSIM.
 
#17
HINT: You don't even need to create custom textures. You could simply use the one's that MS/ACES provided for FS9, or the ones that Joe Binka did as improved versions: vcrain.zip available at AVSIM.
Yeea, I already know them and used them for testing purposes. As anybody could guess, your code works like a charm, thanks Bill! The only thing is that the last one texture in the sequence doesn't disappear after changing the weather condition from rainy day into clear one. I have found out a simple workaround like to make the last/or first texture as an "empty" one (without rain effect) but not tested yet. Also it would be great to have a solution how to slow down a sequence, since the frequency of changing of the textures stays the same (app. about 13-15/sec), no matter how parameteres of (Absolute time, seconds) variable were changed. May it be not even needed by any chance? Frequency speeding would be useful in linking of it with speed of the aircraft at least on the ground which would give some intresting effects.

Anyway, great step and nice gift from you Bill :) Wish you Merry Christmas and all the best!

Radek Koterbski,
IntruderPL

PS. The complete, working code below. Note that I've got a two diffrent "logics" - one for light rain and second one for heavy/moving rain (which starts with speed of A/C greater then 50 kph).

Code:
<!-- An28 custom rain effect on windsheld.  -->	

   <PartInfo>
    <Name>AN28_RainLogic</Name>
    <Visibility>
      <Parameter>
        <Code>
		<!-- SLOW RAIN ANIMATION INITIALIZED BY RAIN & SPEED LOWER THEN 50 KM/H -->
		(P:Absolute time,seconds) 1 % 1 > !
		(A:AMBIENT PRECIP STATE, number) 4 ==
		(A:AIRSPEED INDICATED, kph) 50 &lt;
		and 
		and
			if{
			<!-- LOOP COUNTER -->
				(L:vc_rain,enum) ++ (>L:vc_rain,enum)
			<!-- SEQUENCE OF HEAVY RAIN TEXTURES -->
			<!-- THE FIRST OBJECT/TEX IS WITHOUT RAIN EFFECT -->
				(L:vc_rain,enum) 0 == if{ 1 (>L:Tex00,enum) }
				(L:vc_rain,enum) 1 == if{ 1 (>L:Tex01,enum) 0 (>L:Tex00,enum) }
				(L:vc_rain,enum) 2 == if{ 1 (>L:Tex02,enum) 0 (>L:Tex01,enum) }
				(L:vc_rain,enum) 3 == if{ 1 (>L:Tex03,enum) 0 (>L:Tex02,enum) }
				(L:vc_rain,enum) 4 == if{ 1 (>L:Tex04,enum) 0 (>L:Tex03,enum) }
				(L:vc_rain,enum) 5 == if{ 1 (>L:Tex05,enum) 0 (>L:Tex04,enum) }
				(L:vc_rain,enum) 6 == if{ 1 (>L:Tex06,enum) 0 (>L:Tex05,enum) }
				(L:vc_rain,enum) 7 == if{ 1 (>L:Tex07,enum) 0 (>L:Tex06,enum) }
				(L:vc_rain,enum) 8 == if{ 1 (>L:Tex08,enum) 0 (>L:Tex07,enum) }
				(L:vc_rain,enum) 9 == if{ 1 (>L:Tex09,enum) 0 (>L:Tex08,enum) }
				(L:vc_rain,enum) 10 == if{ 1 (>L:Tex010,enum) 0 (>L:Tex09,enum) }
				(L:vc_rain,enum) 11 == if{ 1 (>L:Tex011,enum) 0 (>L:Tex010,enum) }
				(L:vc_rain,enum) 12 == if{ 1 (>L:Tex012,enum) 0 (>L:Tex011,enum) }
				(L:vc_rain,enum) 13 == if{ 1 (>L:Tex013,enum) 0 (>L:Tex012,enum) }
				(L:vc_rain,enum) 14 == if{ 1 (>L:Tex014,enum) 0 (>L:Tex013,enum) }
				(L:vc_rain,enum) 15 == if{ 1 (>L:Tex015,enum) 0 (>L:Tex014,enum) }
			<!-- RESET LOOP  -->
				(L:vc_rain,enum) 16 == if{ 0 (>L:vc_rain,enum) 0 (>L:Tex015,enum) }
			} 
			<!-- SWITCH OFF RAIN ANMATION ON WINDOWSHIELD -->
			els{ 0 (>L:vc_rain,enum) }
        </Code>
      </Parameter>
    </Visibility>
  </PartInfo>

   <PartInfo>
    <Name>AN28_RainLogic_Moving</Name>
    <Visibility>
      <Parameter>
        <Code>
		<!-- HEAVY RAIN ANIMATION INITIALIZED BY RAIN & SPEED GREATER THEN 50 KM/H -->
		(P:Absolute time,seconds) 1 % 1 > !
		(A:AMBIENT PRECIP STATE, number) 4 ==
		(A:AIRSPEED INDICATED, kph) 50 &gt;
		and 
		and
			if{
				<!-- LOOP COUNTER -->
				(L:vc_mrain,enum) ++ (>L:vc_mrain,enum)
				<!-- SEQUENCE OF RAIN TEXTURES -->
				<!-- THE FIRST OBJECT/TEX IS WITHOUT RAIN EFFECT -->
				(L:vc_mrain,enum) 0 == if{ 1 (>L:MTex00,enum) }
				(L:vc_mrain,enum) 1 == if{ 1 (>L:MTex01,enum) 0 (>L:MTex00,enum) }
				(L:vc_mrain,enum) 2 == if{ 1 (>L:MTex02,enum) 0 (>L:MTex01,enum) }
				(L:vc_mrain,enum) 3 == if{ 1 (>L:MTex03,enum) 0 (>L:MTex02,enum) }
				(L:vc_mrain,enum) 4 == if{ 1 (>L:MTex04,enum) 0 (>L:MTex03,enum) }
				(L:vc_mrain,enum) 5 == if{ 1 (>L:MTex05,enum) 0 (>L:MTex04,enum) }
				(L:vc_mrain,enum) 6 == if{ 1 (>L:MTex06,enum) 0 (>L:MTex05,enum) }
				(L:vc_mrain,enum) 7 == if{ 1 (>L:MTex07,enum) 0 (>L:MTex06,enum) }
				(L:vc_mrain,enum) 8 == if{ 1 (>L:MTex08,enum) 0 (>L:MTex07,enum) }
				(L:vc_mrain,enum) 9 == if{ 1 (>L:MTex09,enum) 0 (>L:MTex08,enum) }
				(L:vc_mrain,enum) 10 == if{ 1 (>L:MTex010,enum) 0 (>L:MTex09,enum) }
				(L:vc_mrain,enum) 11 == if{ 1 (>L:MTex011,enum) 0 (>L:MTex010,enum) }
				(L:vc_mrain,enum) 12 == if{ 1 (>L:MTex012,enum) 0 (>L:MTex011,enum) }
				(L:vc_mrain,enum) 13 == if{ 1 (>L:MTex013,enum) 0 (>L:MTex012,enum) }
				(L:vc_mrain,enum) 14 == if{ 1 (>L:MTex014,enum) 0 (>L:MTex013,enum) }
				(L:vc_mrain,enum) 15 == if{ 1 (>L:MTex015,enum) 0 (>L:MTex014,enum) }
				<!-- RESET LOOP  -->
				(L:vc_mrain,enum) 16 == if{ 0 (>L:vc_mrain,enum) 0 (>L:MTex015,enum) }
			} 
			<!-- SWITCH OFF RAIN ANMATION ON WINDOWSHIELD -->
			els{ 0 (>L:vc_mrain,enum) }
        </Code>
      </Parameter>
    </Visibility>
  </PartInfo> 
  
  <!-- OBJECTS W/LIGHT RAIN TEXTURES VISIBILITY ON -->
  
 	<PartInfo>
		<Name>AN28_Tex00</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex00, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>	 
  
	<PartInfo>
		<Name>AN28_Tex01</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex01, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>

	<PartInfo>
		<Name>AN28_Tex02</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex02, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>

	<PartInfo>
		<Name>AN28_Tex03</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex03, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>

	<PartInfo>
		<Name>AN28_Tex04</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex04, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>	

	<PartInfo>
		<Name>AN28_Tex05</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex05, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>	

	<PartInfo>
		<Name>AN28_Tex06</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex06, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>		
	
	<PartInfo>
		<Name>AN28_Tex07</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex07, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>	

	<PartInfo>
		<Name>AN28_Tex08</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex08, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>		

	<PartInfo>
		<Name>AN28_Tex09</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex09, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>		

	<PartInfo>
		<Name>AN28_Tex010</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex010, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>		
	
	<PartInfo>
		<Name>AN28_Tex011</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex011, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>		

	<PartInfo>
		<Name>AN28_Tex012</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex012, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>		
	
	<PartInfo>
		<Name>AN28_Tex013</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex013, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>		

	<PartInfo>
		<Name>AN28_Tex014</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex014, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>		

	<PartInfo>
		<Name>AN28_Tex015</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex015, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>	

  <!-- OBJECTS W/HEAVY RAIN TEXTURES VISIBILITY ON -->
	
	<PartInfo>
		<Name>AN28_MTex00</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:Tex00, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>	 
  
	<PartInfo>
		<Name>AN28_MTex01</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:MTex01, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>

	<PartInfo>
		<Name>AN28_MTex02</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:MTex02, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>

	<PartInfo>
		<Name>AN28_MTex03</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:MTex03, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>

	<PartInfo>
		<Name>AN28_MTex04</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:MTex04, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>	

	<PartInfo>
		<Name>AN28_MTex05</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:MTex05, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>	

	<PartInfo>
		<Name>AN28_MTex06</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:MTex06, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>		
	
	<PartInfo>
		<Name>AN28_MTex07</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:MTex07, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>	

	<PartInfo>
		<Name>AN28_MTex08</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:MTex08, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>		

	<PartInfo>
		<Name>AN28_MTex09</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:MTex09, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>		

	<PartInfo>
		<Name>AN28_MTex010</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:MTex010, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>		
	
	<PartInfo>
		<Name>AN28_MTex011</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:MTex011, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>		

	<PartInfo>
		<Name>AN28_MTex012</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:MTex012, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>		
	
	<PartInfo>
		<Name>AN28_MTex013</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:MTex013, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>		

	<PartInfo>
		<Name>AN28_MTex014</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:MTex014, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>		

	<PartInfo>
		<Name>AN28_MTex015</Name>
		<Visibility>
			<Parameter>
				<Code>
					(L:MTex015, enum) 1 ==
				</Code>
			</Parameter>
		</Visibility>
	</PartInfo>
 

n4gix

Resource contributor
#18
The only thing is that the last one texture in the sequence doesn't disappear after changing the weather condition from rainy day into clear one.
You need to clear the last texture at the top of the loop:

Code:
(L:vc_rain,enum) 0 == if{ 1 (>L:Tex01,enum) 0 (>L:Tex15,enum) }
I'm not terribly surprised that it works. After all, it's really very simple logic. Aside from which I've been thinking of this for over a year now, but just haven't gotten 'round-to-it' yet... :wizard:
 
#19
I'm not terribly surprised that it works. After all, it's really very simple logic. Aside from which I've been thinking of this for over a year now, but just haven't gotten 'round-to-it' yet... :wizard:
Anyway, that's a great job you've done!

Another request for help is related with animation of beacon light. I've got a small self-illuminated cylinder at the top of tail section. The problem is that it doesn't animate itself and doesn't react properly when the beacon light is switched on (btw beacon effect shows up). The cylinder is visible all the time however should only be visible when the beacon light's switch is on. I've tried (A:LIGHT BEACON,bool) variable and a (A:LIGHT ON STATES,Mask) as well. Is the beacon variable broken in FSX?

Code:
	<PartInfo>
		<Name>AN28_Beacon_Light_Red</Name>
		<AnimLength>360</AnimLength>
		<Animation>
			<Parameter>
				<Code>
					(A:LIGHT BEACON ON, bool) 0 &gt;
						if{ 360 } els{ 0 }					
				</Code>
			</Parameter>
		</Animation>
		<Visibility>
            <Parameter>
                <Code>
					(A:LIGHT BEACON ON, bool) 0 &gt;
                </Code>
            </Parameter>
        </Visibility>		
	</PartInfo>
Intruder
 

n4gix

Resource contributor
#20
First of all, the variable name is incorrect. It is (A:LIGHT BEACON,bool).

Secondly, you are trying to drive an animation based on a single number. The (A:LIGHT BEACON,bool) variable will only be zero or one. In your <Animation> script, you are telling the cylinder to either be rotated to frame 0 or frame 360 (which is frankly the same position anyway!)...

For rotating animation, there are only two choices:

One is to use one of the "Ambient" or "NonRandomAmbient" tags from modeldef.xml. The major disadvantage is that you have no reliable control over the rotation speed or the smoothness. Both versions run at ~18 times/second. 360 frames divided by 18fps is equal to about 20 seconds. That's pretty slow! If you wanted a one second animation, you'd need 18 frames. That's pretty jumpy! Neither seems to be a good solution.

The other, better choice requires that you create your own animation script that works similar to the script we used for the vc rain textures. In other words, a custom variable that counts up to some predetermined number then loops back to zero and repeats ad infinitum until you tell it to stop. Unlike the first method, this one allows you to positively control the speed of the animation by simply varying either the total number of keyframes, a timer to control the firing frequency, or some combination of both.
 
Last edited:
Top