Jump to content
six_ten

windDir help please -- make an arrow point wind direction

Recommended Posts

I want to animate a weathervane -- for now all I want is to get an arrow to point the direction the wind is blowing. 

 

I have an arrow model, an axis for it, and it is defined in model.cfg.  Basically I want it to function like a compass needle but for wind direction.

 

Thought I could just modify the Compass and substitute "windDir" for "direction" but that doesn't work.  How do I translate the wind direction into a source that the weathervane can use?

Maybe an event handler in the ship's init...

 

 

  class Compass
   {
    type="rotation";
    source="direction";
    selection="Compass";
    axis="Compass_Axis";
    memory=1;
    minValue=-3.141590;
    maxValue=3.141590;
    angle0=-3.141593;
    angle1=3.141593;
   };  

  class Weathervane
   {
    type="rotation";
    source="windDir";
    selection="Weathervane";
    axis="Weathervane_Axis";
    memory=1;
    minValue=-3.141590;
    maxValue=3.141590;
    angle0=-3.141593;
    angle1=3.141593;
   }; 

Share this post


Link to post
Share on other sites

I don't think source=direction is necessarily direction in the sense of the scripting command and it's name could just be coincidence.

Share this post


Link to post
Share on other sites

I don't think source=direction is necessarily direction in the sense of the scripting command and it's name could just be coincidence.

 

Ah.  Well, what I was looking at at https://community.bistudio.com/wiki/windDir said that windDir "Returns the current wind azimuth."  I thought I could just plug the azimuth in and the arrow would use that as it's direction.

Share this post


Link to post
Share on other sites

Ah.  Well, what I was looking at at https://community.bistudio.com/wiki/windDir said that windDir "Returns the current wind azimuth."  I thought I could just plug the azimuth in and the arrow would use that as it's direction.

Yes I am aware windDir is a command that returns a number just like direction. That's why I am saying source might not be looking for a scripting command or sqf statement. It might be something on it's own. If anything you need something that returns radians and not degrees since it requires a value between pi and negative pi.

I think this is what you are looking for https://community.bistudio.com/wiki/Model_Config#Animation_sources

You might have to use "user" since I can not find one for wind direction. I think then it is script driven via https://community.bistudio.com/wiki/animate. I know the advanced flight model shows a working wind gauge when in a helicopter.

Share this post


Link to post
Share on other sites

Yes I am aware windDir is a command that returns a number just like direction. That's why I am saying source might not be looking for a scripting command or sqf statement. It might be something on it's own. If anything you need something that returns radians and not degrees since it requires a value between pi and negative pi.

I think this is what you are looking for https://community.bistudio.com/wiki/Model_Config#Animation_sources

You might have to use "user" since I can not find one for wind direction. I think then it is script driven via https://community.bistudio.com/wiki/animate. I know the advanced flight model shows a working wind gauge when in a helicopter.

 

As a test I've substituted "clockSecond" for "windDir" as the source and in game it works:  my arrow ticks every second 1 degree counter-clockwise.  I' think you're right about having to define it.  I'll see if I can find the advanced flight model example in A3.

 

Edit:  strange, watching it I see it goes (counter-clockwise) from 12 to 9 then resets...

Share this post


Link to post
Share on other sites

Edit:  strange, watching it I see it goes (counter-clockwise) from 12 to 9 then resets...

It probably uses a different range for min and max value when using that source.

Share this post


Link to post
Share on other sites

Im still stumped.  It seems so simple, just get wind direction and make the arrow point the way its going...

Share this post


Link to post
Share on other sites

Looking at the Wind page https://community.bistudio.com/wiki/wind   it says that "wind"      "Returns the current wind vector (in m/s) as array [x, z, y]."

 

Is that correct?  aren't they usually arrayed as xyz?

so does that mean I call it like this:

select 0 = x

select 1 = z

select 2 = y

 

Anyhow, getWind returns an azimuth, number between 0 and 360, so if I divide that by 360 I'll have a result between 0 and 1 which I can pass to the bone for animation I think.

 

Is that right?

Share this post


Link to post
Share on other sites

six_ten,

I assume you have inherited class Weathervane from (cfgModels >> NameOfP3d >> Animations), (see https://community.bistudio.com/wiki/Model_Config#config.cpp_model.cfg_relationship ).
As far as I can understand, AnimationSources is for establishing direct user interaction with object, so not needed in your case.
The source string seem to be the controller of your animation, in your case "windDir". So I guess you control your animation with call
myWeatherVane animate ["windDir", phase];
from anywhere from your scrips (animate: aG, eG), where myWeatherVane is your weathervane object (vehicle) and phase is in [-pi, pi] according to your minValue=-3.141590; and maxValue=3.141590;
I guess (again) that compass angle 0 for your axis will be wind's direction also 0 and phase value grows counterclockwise, as radians naturally do.
Then convert windDir to phase using
private ["_wd"];
_wd = windDir;
phase = rad ( if (_wd < 180) then {-_wd} else {360-_wd} );
To be not confused in the future, I recommend rename "windDir" to smth like "WeatherVaneCtrl" or so.
Now you only have to periodically call animate with required phase argument. Start with onEachFrame just to check if it works.
 
Hope that helps.
 
pS. If it does not work, try creating AnimationSource in config.cpp with class name windDir (or replaced).
  • Like 1

Share this post


Link to post
Share on other sites

Thank you very much.  Here's what I have so far:

 

ART\ART_Water\ART_Sloop\Sloop_Bermuda.p3d

in LOD1 etc, a selection named Weathervane

in Memory LOD, a pair of vertically oriented points named Weathervane_Axis

 

ART\ART_Water\ART_Sloop\model.cfg

class CfgSkeletons
{
	class Default
	{
		isDiscrete = 1;
		skeletonInherit = "";
		skeletonBones[] = {};
	};
	class Vehicle: Default {};
	class Ship: Vehicle
	{
		skeletonInherit="Vehicle";
		skeletonBones[]={};
	};
	class civilian_boatSkeleton: Ship
	{
		skeletonInherit = "ship";
		skeletonBones[] = 
		{
		"Compass",		"",
		"Weathervane",		"",		
etc...
//////////////////////////////


class CfgModels
{
	class Default
	{
		sectionsInherit="";
		sections[] = {};
		skeletonName = "";
	};
	class Vehicle: Default
	{
		sections[] ={};
	};
	class Sloop_Bermuda: Vehicle
	{
		skeletonName = "civilian_boatSkeleton";
		sections[] = 
		{
			"Compass",	
			"Weathervane",
etc...
//////////////////////////////

	class Animations
		{
		class Compass
			{
				type="rotation";
				source="direction";
				selection="Compass";
				axis="Compass_Axis";
				memory=1;
				minValue=-3.141590;
				maxValue=3.141590;
				angle0=-3.141593;
				angle1=3.141593;
			};
		class Weathervane
			{
				type="rotation";
				source="user";
				selection="Weathervane";
				axis="Weathervane_Axis";
				memory=1;
				minValue=-3.141590;
				maxValue=3.141590;
				angle0=-3.141593;
				angle1=3.141593;
			};
etc...
//////////////////////////////

ART\ART_Water\ART_Sloop\Scripts\Weathervane.sqf

private ["_WeathervaneWindDir"];
_WeathervaneWindDir = windDir;
phase = rad ( if (_WeathervaneWindDir < 180) then {-_WeathervaneWindDir} else {360-_WeathervaneWindDir} );

Weathervane animate ["windDir", phase];

ART\ART_Water\ART_Sloop\config.cpp

class Sloop_Bermuda: Ship_F
{
etc...
	class AnimationSources
	{
		class Weathervane
		{
		source = user;// "user" = custom src not controlled by some engine value
                initPhase = 0; // Initial value of animations based on this source
		animPeriod = 1; // Coefficient for duration of change of this animation
		};

Share this post


Link to post
Share on other sites

Doesn't work yet -- still have not told it how to find the script (looking for an example of how to do that).

 

Maybe something like this in config.cpp ?  Found an example in the MV-22 in A2 MLODs

  class UserActions
  {			
   class Packon
   {
    displayName=$STR_AM_PACK;
    displayNameDefault="Pack";
    position=PackAction;
    radius=10;
    onlyForPlayer=true;
    condition="this animationphase ""pack_engine_1"" !=1";
    statement="[this,1] execvm ""\ca\air2\mv22\scripts\pack.sqf""";
   };           
///  becomes...
             class Weathervane
			{
				displayName = "";
				onlyforplayer = 1;
				priority = 1;
  				condition="this animationphase ""Weathervane"" !=1";
    				statement="[this,1] execvm ""\ART\ART_Water\Scripts\Weathervane.sqf""";
			};

Share this post


Link to post
Share on other sites

I just accidentally got movement in the weathervane.  Not sure how;  I added

 

_SailingVessel animate ["Weathervane", 1];

 

to an if statement in my script; it moved!  the output was wrong, but still it moved!  huzza!

Share this post


Link to post
Share on other sites

Yeah, I was trying to say it from the beginning:

As far as I can understand, AnimationSources is for establishing direct user interaction with object, so not needed in your case.

...
Now you only have to periodically call animate with required phase argument. Start with onEachFrame just to check if it works.

From my understanding, unless you have builtin animation source, model will not (and probably can not) update itself on its own behalf. You need to perform external command to be pefrormed for that (i.e. animate).

Check this: https://community.bistudio.com/wiki/onEachFrameIt can impact performance, so I don't recommend it as final solution, but should work for first test. After you check everything works, you will need some othe system (e.g. script) that runs animate command for your weathervane. The problem is, I don't see clear now, how to do it properly. I mean, I know how to organize some sort of script in mission which would call some other script periodically. But that seems wrong way for me. There should be some way to make object behaviour entirely object-hosted, so you could place it anywhere and it will work instantly.

Btw, I'm still not sure whether you need AnimationSourrces definitions or not. Can you check everything without them and report here then?

  • Like 1

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×