Jump to content

Recommended Posts

- - - - - - - - - - - - - - - - - - - - - - - - -
EDIT: Solution here.
- - - - - - - - - - - - - - - - - - - - - - - - -

 

Hi all, 

 

I've been spending a while trying to figure out the proper method to attach a vest to a dog and correctly move it with the animations. Creation of dog and initial AttachTo are working fine, but I'm having trouble matching the direction of the vest to the dog's position. This is what I have been trying to work with so far, but it does not match correctly: 

_dog = dogDmy;
_vest = "Vest_V_HarnessO_gry" createVehicle [0,0,0];
_vest attachTo [_dog,[0,-0.4,-0.54],"spine2"];

_n=[_dog,_vest] spawn
{
	_dog = _this select 0;
	_vest = _this select 1;
	while {_vest in (attachedObjects _dog)} do 
	{
		_vest setVectorDirAndUp [(_dog selectionPosition "spine2") vectorFromTo (_dog selectionPosition "hips"),[0.01,0.01,-0.99]];
		sleep .1;
	};
};

There are similarities between this and a couple other scripts people have written, but they don't seem to work entirely for a dog. 
https://forums.bohemia.net/forums/topic/189737-attachto-trying-to-attch-a-lamp-on-torret/
http://killzonekid.com/arma-scripting-tutorials-uav-r2t-and-pip/ 

At the minute I am using While instead of a Draw3D or EachFrame EH to avoid unnecessary use of resources. 

Dog creation for testing:

Spoiler

_side = side player;
_grp = createGroup _side;
_dog = _grp createUnit ["Alsatian_Sandblack_F", position player, [], 0, "CAN_COLLIDE"];
[_dog] join _grp;
_dog setSpeaker "NoVoice";
_dog setBehaviour "CARELESS";
_dog setVariable ["BIS_fnc_animalBehaviour_disable", true];
_dog switchMove "Dog_Stop";
dogDmy = _dog;

 

Thank you in advance!

  • Like 1
  • Haha 1

Share this post


Link to post
Share on other sites
6 hours ago, PortalGunner said:

Hi all, 

 

I've been spending a while trying to figure out the proper method to attach a vest to a dog and correctly move it with the animations. Creation of dog and initial AttachTo are working fine, but I'm having trouble matching the direction of the vest to the dog's position. This is what I have been trying to work with so far, but it does not match correctly: 


_dog = dogDmy;
_vest = "Vest_V_HarnessO_gry" createVehicle [0,0,0];
_vest attachTo [_dog,[0,-0.4,-0.54],"spine2"];

_n=[_dog,_vest] spawn
{
	_dog = _this select 0;
	_vest = _this select 1;
	while {_vest in (attachedObjects _dog)} do 
	{
		_vest setVectorDirAndUp [(_dog selectionPosition "spine2") vectorFromTo (_dog selectionPosition "hips"),[0.01,0.01,-0.99]];
		sleep .1;
	};
};

There are similarities between this and a couple other scripts people have written, but they don't seem to work entirely for a dog. 
https://forums.bohemia.net/forums/topic/189737-attachto-trying-to-attch-a-lamp-on-torret/
http://killzonekid.com/arma-scripting-tutorials-uav-r2t-and-pip/ 

At the minute I am using While instead of a Draw3D or EachFrame EH to avoid unnecessary use of resources. 

Dog creation for testing:

  Reveal hidden contents


_side = side player;
_grp = createGroup _side;
_dog = _grp createUnit ["Alsatian_Sandblack_F", position player, [], 0, "CAN_COLLIDE"];
[_dog] join _grp;
_dog setSpeaker "NoVoice";
_dog setBehaviour "CARELESS";
_dog setVariable ["BIS_fnc_animalBehaviour_disable", true];
dogDmy = _dog;

 

Thank you in advance!

I cannot help ya brother, BUT.... there's someone around here which know DOGS stuff...he is the GURU, the absolute master of dogs..."DA DOGGY MAN"😜....that is @johnnyboy...

The "vest on a dog" is something he is/was looking into for quite some time...maybe you guys could help each other. So we ALL can finally have proper combat-dogs with proper insignias if I'm not asking too much!..hahahaha... 😋😋😋

  • Like 1

Share this post


Link to post
Share on other sites

Maybe we can just make custom dog vests, with the dog skeleton that actually fit the dog and natively work on them without scripting.
If we can make lego man with lego uniforms, then we can make dogs with vests!

  • Like 2

Share this post


Link to post
Share on other sites

If I were any good with models I would certainly be giving those dogs the fashionable outfits they deserve! c;
JBOY does have the best dog script in my opinion. This script is basically a small part of my edit of his (I've added too much to list >.>). I might consult him if he isn't busy. 
Unfortunately working with vectors and vectorDirAndUp is the one area I am not at all experienced in. 

It might be possible, if I can get the exact pitch/yaw/bank of the dog's spine, to send that data through example 1 from setVectorDirAndUp on the wiki.

// set exact yaw, pitch, and roll
_y = 45; _p = -80; _r = 0;
_vest setVectorDirAndUp [
	[ sin _y * cos _p,cos _y * cos _p,sin _p],
	[ [ sin _r,-sin _p,cos _r * cos _p],-_y] call BIS_fnc_rotateVector2D
];

But getting that data in the first place escapes me.
It's also a completely different method than the two scripts I linked to earlier. It might just be easier to find a variant of those that works with the dog model, but finding that is also proving to be a hassle.

Share this post


Link to post
Share on other sites
27 minutes ago, PortalGunner said:

It might be possible, if I can get the exact pitch/yaw/bank of the dog's spine, to send that data through example 1 from setVectorDirAndUp on the wiki.

Hi PortalGunner.  I tried attaching a vest to a dog a year ago or more, and it really doesn't work very well.  By fiddling with setVectorDirAndUP you can get it placed ok for a stationary dog.  But once he starts moving its all over  the place.  I don't know if I tried attaching to spine, that would be better.

 

For getting the right vectorDir and vectorUp values, I place a vest in the editor and use the rotation tool to get it oriented the way I want.  I then play in Editor and use console to get the vectorDir and Up values for the vest.  And use those hardcoded captured  values to attach to dog.  Maybe that technique will help you.  Make sample vest a simple object so gravity doesn't drop it to the ground when you play the test mission.

 

I don't have the sample code any more for the dog and vest experiments.

 

32 minutes ago, PortalGunner said:

Unfortunately working with vectors and vectorDirAndUp is the one area I am not at all experienced in.

I find that a huge pain in the ass as well.

 

Good luck mate!

 

Here's the old gag screenshot of UDT Boomer with a vest and dry dive helmet:

udt_Boomer.jpg

  • Like 5
  • Thanks 1

Share this post


Link to post
Share on other sites

How about

_vest setVectorDirAndUp [vectorDir _dog,[0.01,0.01,-0.99]];

?

Share this post


Link to post
Share on other sites
2 hours ago, haleks said:

_vest setVectorDirAndUp [vectorDir _dog,[0.01,0.01,-0.99]];

 

I believe vectorDir is similar to vectorFromTo but uses the direction of the 'object' itself rather than the direction between two mempoints (hip/spine). Still, I will test it.
 

4 hours ago, johnnyboy said:

Hi PortalGunner.  I tried attaching a vest to a dog a year ago or more, and it really doesn't work very well.  By fiddling with setVectorDirAndUP you can get it placed ok for a stationary dog.  But once he starts moving its all over  the place.  I don't know if I tried attaching to spine, that would be better.

It's the man himself! That screenshot is hilarious but awesome!
Attaching to spine means its position will always be in the right place, no matter the dogs animation. Unfortunately that only works for the position, not rotation, so when the dog sits, the vest will stay horizontal and not pitch with the dogs back. Hence the use of setVectorDirAndUp. I'm not sure setting the vest as a simple object is necessary if you then use attachTo. 

Something I might try:

Spoiler

_dog = dogDmy;
_vest = "Vest_V_HarnessO_gry" createVehicle [0,0,0];
_vest attachTo [_dog,[0,-0.4,-0.54],"spine2"];

_n=[_dog,_vest] spawn
{
	_dog = _this select 0;
	_vest = _this select 1;
	while {_vest in (attachedObjects _dog)} do 
	{
		_vest setVectorDirAndUp [
			(_dog selectionPosition "spine2") vectorFromTo (_dog selectionPosition "hips"),
			((_dog selectionPosition "leftshoulder") vectorFromTo (_dog selectionPosition "hips")) 
			vectorCrossProduct 
			((_dog selectionPosition "rightshoulder") vectorFromTo (_dog selectionPosition "hips"))
		];
		sleep .1;
	};
};

 

 

Share this post


Link to post
Share on other sites
8 minutes ago, PortalGunner said:

Attaching to spine means its position will always be in the right place, no matter the dogs animation. Unfortunately that only works for the position, not rotation, so when the dog sits, the vest will stay horizontal and not pitch with the dogs back. Hence the use of setVectorDirAndUp. I'm not sure setting the vest as a simple object is necessary if you then use attachTo. 

If that's the case, maybe best thing is to not allow dog to sit.  You could remove the sit command from the dog menu.  Then you don't need crazy logic to accommodate dog's current animation.

 

If your attachTo spine code works, I just might have to do the UDT boomer mission after all!

 

See, I'm not crazy...

 

  • Like 1
  • Haha 1

Share this post


Link to post
Share on other sites

What a cute dog johnnyboy.

An update: In some respect I have pitch working, but it does not bank/roll with the dog when it keels over (and dies). As well as this, the offset of the vest model means that when it sits, the vest moves off behind of the body!

With:

_tilt = (_dog selectionPosition "spine2") vectorFromTo (_dog selectionPosition "hips");
_vest setVectorDirAndUp [[0.01,-0.99,_tilt select 2],[0.01,0.01,-0.99]];

vectorCrossProduct from the snippet I posted earlier is just returning [0,0,0]

  • Like 1

Share this post


Link to post
Share on other sites
26 minutes ago, PortalGunner said:

An update: In some respect I have pitch working, but it does not bank/roll with the dog when it keels over (and dies). As well as this, the offset of the vest model means that when it sits, the vest moves off behind of the body!

I had the same problem when moving.  And I forgot about dying.  One thing good about dogs though, is they have only one death pose.  So you could capture and hardcode the right vectorDirAndUP for a dead dog.  (actually you have to do all this twice for both types of dogs--Alsation and the smaller one).

 

For moving, you could write a loop that changes attachTo position for each animation:  Stop, Run, Walk, Sprint.  I personally decided it wasn't worth the effort. But if you get it done, kudos to you sir!

  • Like 1

Share this post


Link to post
Share on other sites

When I eventually finish my full edit I will contact you in case you're interested, johnny.

I found out that the "hips" selection is actually not in line with the body and for some reason is on the right leg. 
Here's where I'm at with this:

// Average vector from 2 back legs to spine
_dir = (((_dog selectionPosition "spine2") vectorFromTo (_dog selectionPosition "leftupleg")) vectorAdd ((_dog selectionPosition "spine2") vectorFromTo (_dog selectionPosition "rightupleg"))) vectorMultiply 0.5;

// Vector from model origin to spine
_up = (_dog selectionPosition "spine2") vectorFromTo [0,0,0];

// Adding a small offset on the pitch since we are matching to legs, not hips
_vest setVectorDirAndUp [[_dir select 0,_dir select 1,(_dir select 2) + 0.4],_up];

It's a little funky on death, but it works. 
The major problem now is that the centre of the vest is not the actual centre, so when the dog sits, the vest starts moving behind the dog. 
Is there a way to set the model centre of the vest? Or to calculate attachTo with an offset on the vest and not just the dog?

Share this post


Link to post
Share on other sites
1 hour ago, PortalGunner said:

The major problem now is that the centre of the vest is not the actual centre, so when the dog sits, the vest starts moving behind the dog. 
Is there a way to set the model centre of the vest? Or to calculate attachTo with an offset on the vest and not just the dog?

I like your perseverance.  attachTo is relative to object attaching to (i.e. dog), so sitting will be a problem.  The only solution for that IMO is a loop monitoring dog animation (or an animation changed eventHandler perhaps?), that detects dog sit animation, and then applies a different attachTo position and maybe different vector up/down if needed. 

 

When can we see a short vid of dog moving with vest attached?  🙂

 

  • Like 1

Share this post


Link to post
Share on other sites
1 hour ago, johnnyboy said:

I like your perseverance.  attachTo is relative to object attaching to (i.e. dog), so sitting will be a problem.  The only solution for that IMO is a loop monitoring dog animation (or an animation changed eventHandler perhaps?), that detects dog sit animation, and then applies a different attachTo position and maybe different vector up/down if needed. 

 

When can we see a short vid of dog moving with vest attached?  🙂

 

I have it working! Well, mostly. 
I've attached an invisible object to the spine, and am attaching the vest to that with an offset. setVectorDirAndUp now acts on the invisible object instead. 
The only problem now is that there's a bit of clipping when the dog sits down, just because of the way the MemPoints I'm getting the directions from move.
I have to find a balance where it doesn't look to far off when standing but doesnt clip through when sitting.

  • Like 1

Share this post


Link to post
Share on other sites
Posted (edited)

This took the better part of a day, but it's in a working state. Lag with the vest adjustments is affected by how often the direction of the vest is set. For me, a while loop with a short sleep is fine, and the lag provides a nice little 'bounce' to the vest when the dog is running. For faster refresh, reduce the sleep time or use a draw3D or EachFrame event handler. Although the full script I am working on will be MP compatible, the code below is local. Any object can be attached to the Mark object if attach location is known. 
 

 

Completed solution code:

Spoiler

// Create attach point to dog
_mark = "Sign_Sphere10cm_F" createVehicle [0,0,0];
hideObjectGlobal _mark;
_mark enableSimulation false;
_dog disableCollisionWith _mark;
_mark attachTo [_dog,[0,0,0],"spine2"];
_mark setVectorDirAndUp [[0.000334613,-0.999281,0.0379131],[-0.00888041,-0.0379145,-0.999241]];

_gearObj = selectRandom [ // classname, attach pos, ace-interact pos
	["Vest_V_Chestrig_khk",		[0,0.44,0.52],	[0,-0.2,-0.65]],
	["Vest_V_TacChestrig_cbr_F",	[0,0.44,0.52],	[0,-0.2,-0.65]],
	["Vest_V_HarnessO_gry",		[0,0.44,0.52],	[0,0,-0.65]]
];

// Create vest (any class that works with same attach point)
_vest = (_gearObj select 0) createVehicle [0,0,0];
_dog setVariable ["vVestObj",_vest,true];

// Exclude if you want to take vest off of dog (You would have to run this script again to readd a new one)
// This does however prevent inventory access (solution further down in post)
_vest setdamage 1;

_vest enableSimulation false;
_dog disableCollisionWith _vest;
_mark disableCollisionWith _vest;

// Attach vest and set up vest movement
_vest attachTo [_mark,_gearObj select 1];
_n=[_dog,_mark,_vest] spawn {
	_dog = _this select 0;
	_mark = _this select 1;
	_vest = _this select 2;
	while {_vest in (attachedObjects _mark)} do {
		_tilt = (((_dog selectionPosition "spine2") vectorFromTo (_dog selectionPosition "leftupleg")) vectorAdd ((_dog selectionPosition "spine2") vectorFromTo (_dog selectionPosition "rightupleg"))) vectorMultiply 0.5;
		_up = (_dog selectionPosition "spine2") vectorFromTo [0,0,0];
		if ((_tilt select 2) < -0.67) then {
			_tilt set [2,-0.67];
		};
		_mark setVectorDirAndUp [[_tilt select 0,_tilt select 1,(_tilt select 2) + 0.45],_up];
		sleep .05;
	};

	// Delete attach point if vest gone
	_dog setVariable ["vVestObj",objNull,true];
	{
		if (!isNull _x) then {
			detach _x;
			deleteVehicle _x;
		};
	} forEach [_mark,_vest];
};

 


The vest spawned in the above code has its scroll menu/inventory disabled to prevent pickup. If you want inventory access, use the below code also:

Spoiler

// Create inventory box (any class of box from CfgVehicles Equipment)
_box = createVehicle ["Box_Wps_F",[0,2,0],[],0,"NONE"];
_box hideObjectGlobal true;
_box allowDamage false;
_dog setVariable ["vGearBox", _box, true];
clearItemCargoGlobal _box;
clearWeaponCargoGlobal _box;
clearMagazineCargoGlobal _box;

// ACE interaction if ACE exists, otherwise scroll menu action
if (isClass(configFile >> "CfgPatches" >> "ace_main")) then {
	private _condition = {
		isNull objectParent player
	};
	private _statement = {
		0 = [_this select 1,_this select 2] spawn {
			params ["_player", "_params"];
			private _dog = _params select 0;
			private _gear = _dog getVariable ["vGearBox",objNull];
			private _vest = _dog getVariable ["vVestObj",objNull];
			if ((!isNull _gear) && (!isNull _vest)) then {
				_gear setpos position _vest;
				_player action ["Gear", _gear];
				disableSerialization;
				waitUntil {sleep .3; !isNull (findDisplay 602)};
				waitUntil {sleep .3; isNull (findDisplay 602)};
				_gear setpos [0,2,0];
			};
		};
	};
	private _action = [(str _dog) + "_dogGear","Dog Supplies","\A3\ui_f\data\igui\cfg\actions\gear_ca.paa",_statement,_condition,{},[_dog],_gearObj select 2,5] call ace_interact_menu_fnc_createAction;
	[_vest, 0, [], _action, true] call ace_interact_menu_fnc_addActionToObject;
} else {
	_act1 = _handler addaction ["Dog Supplies",{(_this select 3) setpos position (_this select 1); (_this select 1) action ["Gear", (_this select 3)]; waitUntil {sleep .3; !isNull (findDisplay 602)}; waitUntil {sleep .3; isNull (findDisplay 602)}; (_this select 3) setpos [0,2,0]}, _box, 6, false, false, "", "(isNull objectParent _this) && (!isNull(_this getvariable [""vDog"",objNull])) && ((_this distance (_this getVariable [""vDog"",objNull]))<5)"];
	// Saving action id for removal
	_handler setVariable ["vGearAct", _act1, true];
};

 


If you can think of any improvements, I'm all ears!

Edited by PortalGunner
  • Like 6
  • Thanks 1

Share this post


Link to post
Share on other sites

I'm impressed man, that is really good!

  • Like 3
  • Thanks 1

Share this post


Link to post
Share on other sites
5 hours ago, PortalGunner said:

_tilt = (((_dog selectionPosition "spine2") vectorFromTo (_dog selectionPosition "leftupleg")) vectorAdd ((_dog selectionPosition "spine2") vectorFromTo (_dog selectionPosition "rightupleg"))) vectorMultiply 0.5;

WTF?  I never would have came up with that.  Wow.  How did you figure that out?

 

  • Like 2

Share this post


Link to post
Share on other sites
30 minutes ago, johnnyboy said:

WTF?  I never would have came up with that.  Wow.  How did you figure that out?

 

That specific line is to average out the vectors between the upper back legs and the spine. Because apparently there's barely any mempoints down the centre of the body >n<
The only reason I was able to figure that out was because the vector commands are similar to normal math commands. Thank goodness we have the wiki.

  • Like 3

Share this post


Link to post
Share on other sites

Nice. I would love this to work for my next campaign as well. I always got frustrated with objects not moving right with the dog.

  • Like 2

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

×