UNN 0 Posted November 4, 2012 Anyone able to write a function(s) that would ensure an object attached to an aircraft, will always point north with 0 pitch and bank? Afraid my maths isn't up to it :( Share this post Link to post Share on other sites
twirly 11 Posted November 4, 2012 Have a play with this... but it would take repeated calls to keep it oriented the way you want. Along the lines of setpositioning it every 0.05 seconds or less. Might cause some stress on the system and in a MP game not sure how this would look. fn_orientObject.sqf:- /* [b]call with:[/b] nul = [object,direction,angle,pitch] call fn_orientObject */ private ["_obj","_dir","_ang","_pit","_vecdx","_vecdy","_vecdz","_vecux","_vecuy","_vecuz"]; _obj = _this select 0; _dir = _this select 1; _ang = _this select 2; _pit = _this select 3; _vecdx = sin(_dir) * cos(_ang); _vecdy = cos(_dir) * cos(_ang); _vecdz = sin(_ang); _vecux = cos(_dir) * cos(_ang) * sin(_pit); _vecuy = sin(_dir) * cos(_ang) * sin(_pit); _vecuz = cos(_ang) * cos(_pit); _obj setVectorDirAndUp [[_vecdx,_vecdy,_vecdz],[_vecux,_vecuy,_vecuz]]; true In your init.sqf:- fn_orientObject = compile preprocessFileLineNumbers "fn_orientObject.sqf"; Share this post Link to post Share on other sites
blackmamb 2 Posted November 4, 2012 Might cause some stress on the system and in a MP game not sure how this would look. Yeah, usually repeated use of setPos, setDir, setVelocity and other stuff like that results in some ugly stuttering in MP. Share this post Link to post Share on other sites
kylania 568 Posted November 4, 2012 I'm frightened that UNN is asking something. :eek: Every time I've come across something totally obscure and magical it's usually been a UNN post that's provided the answer! :) Share this post Link to post Share on other sites
UNN 0 Posted November 11, 2012 (edited) Hi, Thanks for the replies so far. Setting the vector of an object is easy enough thanks to the many functions already available, that's not the problem. The problem I have is setting the vector of an object that's attached to another object. In this case I want to keep the child (the attached object) orientated so it always points north and always stays horizontal along both axis. Let me explain in more detail. If the parent object is pointing 90 degrees (East) , then the child's direction has to be set to 0-90. If the parent object has its nose pointing down by 20 degrees, then the child's nose has to point up by -20 degrees. All this sounds straight forward until you start dealing with attached objects. When the parent is pointing East with it's nose down by 20 degrees, the child object orientated to point north now has it's wings angled to 20 not its nose. Set the parents direction back to 0 degrees (North) then the child now has it's nose pointing down again. What I described above is quite simple compared to when the parent object is orientating along all three axis. Think of it another way, I want a set vector function with an additional parameter. The parameter is "Relative (True\False)". So I could call the following: _child attachTo [_parent,[0,20,0]; [_child,0,0,0,false] call _function; When "Relative" is false, the function would ignore the orientation of the object the child is attached to. Instead it would always be pointing north, in a straight and level direction. Hence the [0,0,0] array being passed. I've made an example mission which will hopefully communicate this problem better than I can. http://www.freefilehosting.net/unnorientateattachedutes Thanks Edited November 11, 2012 by UNN Share this post Link to post Share on other sites
VictorFarbau 0 Posted November 14, 2012 If I understand correctly you would like to attach an object that behaves like water. Always leveled and in your case always facing north. So the script would constantly need to calculate the correct pitch and bank relative to the parents object and execute some setVector statement. Why not use a simple setDir and then a loop of setPos with a position relative to the parent object instead? Both approaches require to be run every 0.01 seconds to provide best results anyway. Or do you think attachTo + setVector causes less delay in positioning compared to setPos when in MP? In SP there's never an issue usually, in MP there can be delays even with attachTo objects, as I have observed a couple of times during MP games. And if you're concerned about the parent object crashing into the child object during movement you could still execute "enableSimulation false" on the child object as long as attached to the parent. Just my 2 cents, VictorFarbau Share this post Link to post Share on other sites
UNN 0 Posted November 14, 2012 If I understand correctly you would like to attach an object that behaves like water That’s exactly the effect I want to achieve. Why not use a simple setDir and then a loop of setPos with a position relative to the parent object instead? That’s what I was doing and it work well enough, even in MP. But since patch 1.60 all thats changed. It looks awful now, even in single player. Guess they introduced some sort of script interrupt. Share this post Link to post Share on other sites
VictorFarbau 0 Posted November 15, 2012 Yep, clear. After attaching a child to a parent object the child will assume the parent as its coordinate system and north means being straight aligned with the parent. As I see it the calculation would be: 1. Calculate delta of parent's vector and real world [0,0,1] 2. Apply inverted delta to the child object Surely enough quite annoying to calculate :) Post 2 shows the translation from degrees to vector which is needed for step 2. Haven't wrapped my head around step 1 yet and it shouldn't be rocket science but I saw many people giving up on setVector so I won't talk too big. VictorFarbau Share this post Link to post Share on other sites
derdoe 10 Posted November 15, 2012 (edited) Quite easy, i write down some pseudo code: a = root object b = child object direction b is relative to the orientation of object a. If object a has a heading of 90, object a's heading - 90 returns object b's orientation. if(dir a <= 180){ dir b = - dir a; }else{ dir b = 360 - dir a } Is that what you are looking for? Example: dir a = 110 result: dir b= - 110 dir a= 240 result: dir b = + 120 Edited November 15, 2012 by derdoe Share this post Link to post Share on other sites
UNN 0 Posted November 15, 2012 Haven't wrapped my head around step 1 yet and it shouldn't be rocket science but I saw many people giving up on setVector That’s what I find so frustrating, I have a vague idea of what needs to be done. But even regular vectors are beyond my maths skills it seems. Again I can't stress how much I appreciate any help with vectors. It's so demoralizing, having a project stall, when it’s almost near completion. @derdoe Unfortunately not, applying this to one axis is easy enough. Combining all three gets much more complicated. Share this post Link to post Share on other sites
Sealife 22 Posted November 15, 2012 If you attach it to an animated Vertices does it still retain the direction of the parent object , was thinking if both objects are available in mlod you could perhaps try to animate the vert to which the object attached to, I know from experience the attached object does follow the animated vert rather than the parent objects when animated but cant from memory remember if it would also turn with the animation also . thinking you could create an alternative compass vert and use the Mirror define to set it at - 180 possibly. Share this post Link to post Share on other sites
VictorFarbau 0 Posted November 16, 2012 (edited) I almost got it, it needs some finetuning but it should work eventually. It's not only about understanding the applied vector space but also the sequence of commands is essential apparently. When I'm done I'll post it here. If you don't hear back I jumped out of the window. Cheers, VictorFarbau Edited November 16, 2012 by VictorFarbau Share this post Link to post Share on other sites
twirly 11 Posted November 17, 2012 If you don't hear back I jumped out of the window. Same here... ready to jump out the window on this one! LOL! Share this post Link to post Share on other sites
VictorFarbau 0 Posted November 18, 2012 (edited) No success and my gut feeling is, even when correctly computed it will still look completely dorky. Here's what I observed during my attempts: When A is attached to B: 1. setVectorDir alone will just cause unit A to flicker once 2. setVectorDirandUp applies the horizontal position of A correctly (array 1 of 2) but seems to completely ignore the pitch and bank array (array 2 of 2) 3. setVectorUp needs to be applied on A but can only be used in conjuction with a preceding setVectorDirandUp 4. calculation of a identical pitch and bank requires compensation for current vector of B PLUS misalignment between model centers PLUS distance between A and B So keeping the north orientation through setVectorDirandUp is no problem (sin and cos of parents direction), pitch and bank remains more or less out of control even though I bascially understand how they are supposed to work now. If the desired flat north orientation works then still this looks unnatural as the rotational center of A and B won't match (point 4, downside of attachto). I already spent 4h with this and the results just look stupid so I will put this idea to rest; maybe attachTo + setVector just doesn't cut it for this requirement. Sorry UNN, it just doesn't work out correctly for me and I can't figure out why. In my opinion a classical 3d vector command [degree left/right, degree up/down, degree forward/backward] would be more helpful compared to this freaky 2 * 2d vector concept. And guess what, if you had VBS2 you'd solve your problem in 2 minutes (parameter "relative"): VBS2: http://resources.bisimulations.com/wiki/setVectorDirAndUp VictorFarbau Edited November 18, 2012 by VictorFarbau Share this post Link to post Share on other sites
UNN 0 Posted November 22, 2012 Sorry UNN, it just doesn't work out correctly for me and I can't figure out why. No worries, thanks for trying. I didn't rule out the fact that Arma's vector commands could either be wrong or limited in some way. But I wasn't in a position to say. And guess what, if you had VBS2 you'd solve your problem in 2 minutes (parameter "relative"): Actually, that param does nothing in the function, it defaults to false. While it is taking me some time, as it still isn't straight forward, I am making some progress with cfg animations as Thromp suggested. Not by attaching to them, but simple because you can handle each rotation separately, rather than setVector which tries to do everything in one go. I'm not in a position to say it will work atm, otherwise I would have let you all know sooner. But from the sounds of it, I think setVector is a dead end? Thanks for all your help. Share this post Link to post Share on other sites
Sealife 22 Posted November 22, 2012 Don't forget also , sometimes it is a last resort to make the thing your attaching a Man class and give it an exclusive Crew position, this way you can animate the Cargo proxy. in recent past I have found when doing any cargo stuff and trying to beat the internal view render showing things outside the vehicle, its simpler to give the cargo a Animal based config inheritance and simply moveincargo the piece and animate it the proxy (forklifts or whatever I am messing with for example. just another Angle ( pun) Share this post Link to post Share on other sites
galzohar 31 Posted November 22, 2012 Basically, each object has 2 vectors representing where it is facing. 1 represents where the top is facing, and another where the front is facing. One vector is facing directly north with its top facing directly up, and the other in an arbitrary direction. Let's start with the facing direction (you can then do the same with the top direction alter). The objects vector you get from getVectorDir (let's call it A), while the other is [0,1,0] (facing north - let's call it B). The direction around which we need to rotate to counteract the orientation of the root object is U = A x B: 1,2,3 would normally correspond to the x,y,z axes, but remember in Arma y -> -y and phi -> -phi in all formulas due to the difference between the conventions of map coordinate systems as opposed to the ones usually used in math formulas such as the ones you would find on wikipedia. Now that we have the direction of the axis around which we rotate, we need to normalize it so that Ux'^2 + Uy'^2 + Uz'^2 = 1. So the normalized vector U' = U / (Ux^2 + Uy^2 + Uz^2). The angle at which we rotate is easy: Theta = arccos ((A dot B)/(|A||B|)) A dot B = A1B1 + A2B2 + A3B3 |A| = sqrt (A1^2 + A2^2 + A3^2) And same for |B|. Now the rotation matrix (from wikipedia) would be: So now you need to do a simple matrix vector multiplication to get your desired vectorDir. I'll let you look up the formulas for the multiplication. Let's call the result C = R dot A. As long as you remember to reverse the y coordinates (so [Ax,Ay,Ax] is changed to [Ax,-Ay,Az] and [0,1,0] is changed to [0,-1,0]), and in the end you reverse the y axis of C again (so [Cx,Cy,Cz] is changed to [Cx,-Cy,Cz] before you setVectorDir, it should be good. Repeat the exact same process with the 2 getVectorUp and set the result with setVectorUP and you *should* be fine if you got all the linear and vector algebra correctly. Of course, setVectorDir and setVectorUp repeatedly might stutter, as already been mentioned, but at least it'll point in the right direction when the script does get a chance to execute. Share this post Link to post Share on other sites
twirly 11 Posted November 22, 2012 I spent hours looking at it as Trig rotation and couldn't get it to work. Gave up in the end. Will try to digest the vector math. Share this post Link to post Share on other sites
UNN 0 Posted November 22, 2012 Thanks galzohar, I would really like to learn this stuff for myself and I would still like a vaector based function as well. Will try plowing through your notes. in recent past I have found when doing any cargo stuff and trying to beat the internal view render showing things outside the vehicle, its simpler to give the cargo a Animal based config inheritance and simply moveincargo the piece and animate it the proxy (forklifts or whatever I am messing with for example. Thanks, I used a similar myself back in the Arma1 days. Not what I need for this task, but I think PhysX in Arma3 should be an improvement, if you want to transport cargo around. Share this post Link to post Share on other sites
sakura_chan 9 Posted November 23, 2012 I tried doing this lately, I was making a laser designator camera for a plane script. I was trying to attach a turret that would stay level and point in the same direction when the plane moved. The only way I could do it easily was to use visiblepostion: _plane = plane; _turret = turret; while {true} do { _turret setposATL [visiblePosition _plane select 0, visiblePosition _plane select 1, (visiblePosition _plane select 2) + 10]; }; You could use some older code to give it an offset from the model, because modeltoworld doesn't use the visible layer anymore (even though it should). The only problem was that it wigs out if you are in the attached vehicle (at least for static guns). If it is manned by ai then it is ok. Share this post Link to post Share on other sites
galzohar 31 Posted November 24, 2012 (edited) By the way, I think I was wrong about flipping the Y axis. It's actually only the angles that are defined differently. X x Y = Z in Arma just like in a standard coordinate system, so you don't need to flip any directions, however the angles are defined differently (which don't matter in this case since you're only using vectors defined by [x,y,z]). If you're using setPos rather than attachTo, why not just use setPosASL relative to the plane's setPosASL? Sea level is always the same reference point no matter where you are, and at least doesn't seem to give any trouble regarding getting the correct height. As for lasers, though, the real problem is not so much about keeping them pointed in the same real-world direction, and more about keeping them pointed at the same spot on the ground, which is much more difficult to do with scripting (as you can see, BIS scripts try to do it but don't do it very well at all). Not sure how easy it is to keep a camera pointed at the same spot on the ground with a real UAV/plane, though, I'll have to do some digging about that. Edited November 24, 2012 by galzohar Share this post Link to post Share on other sites
Master85 1 Posted November 24, 2012 //calculate the dot product of 2 3-dimensional vectors fn_dot= { private ["_vec0", "_vec1", "_vec0X", "_vec1X", "_vec0Y", "_vec1Y", "_vec0Z", "_vec1Z"]; _vec0 = _this select 0; _vec0X = _vec0 select 0; _vec0Y = _vec0 select 1; _vec0Z = _vec0 select 2; _vec1 = _this select 1; _vec1X = _vec1 select 0; _vec1Y = _vec1 select 1; _vec1Z = _vec1 select 2; (_vec0X * _vec1X) + (_vec0Y * _vec1Y) + (_vec0Z * _vec1Z) }; //calculate the cross product of 2 3-dimensional vectors fn_cross= { private ["_vec0", "_vec1", "_vec0X", "_vec1X", "_vec0Y", "_vec1Y", "_vec0Z", "_vec1Z"]; _vec0 = _this select 0; _vec0X = _vec0 select 0; _vec0Y = _vec0 select 1; _vec0Z = _vec0 select 2; _vec1 = _this select 1; _vec1X = _vec1 select 0; _vec1Y = _vec1 select 1; _vec1Z = _vec1 select 2; [ (_vec0Y * _vec1Z) - (_vec0Z * _vec1Y), (_vec0Z * _vec1X) - (_vec0X * _vec1Z), (_vec0X * _vec1Y) - (_vec0Y * _vec1X) ] }; //project 3-dim vector _vec onto axes of local coord system of _obj //"_obj worldToModel _vec" without translation - i.e. rotation only fn_proj= { private ["_obj", "_vec", "_xAxis", "_yAxis", "_zAxis"]; _vec = _this select 0; _obj = _this select 1; _yAxis = vectorDir _obj; _zAxis = vectorUp _obj; _xAxis = [_yAxis, _zAxis] call fn_cross; [ [_vec, _xAxis] call fn_dot, [_vec, _yAxis] call fn_dot, [_vec, _zAxis] call fn_dot ] }; _child setVectorDirAndUp [[[0,1,0],_parent] call fn_proj,[[0,0,1],_parent] call fn_proj]; Share this post Link to post Share on other sites
galzohar 31 Posted November 25, 2012 I thought there should be something easier than rotations :) Share this post Link to post Share on other sites