sjakal 13 Posted March 14, 2016 Disregarding if this is realistic or not for the year 2035 where ArmA III occurs, how would I go about measuring distance along my rifle's IR laser attachment while active? I already have an eventhandler for drawing text/icons on-screen (or I could use a simple hint message), so all I really need is: Find primaryWeapon selectionPosition + direction of the IR laser emitter if my weapon has one attached. Determine if the attachment is currently activated (there should be NO rangefinding while laser is OFF). Imitate the laser's collision with the environment to find the laser's end-point to measure the distance to. Scripting hints for any of the three points above will be much appreciated, as will references to similar/related posts and answers. Thanks in advance lads/ladettes! Share this post Link to post Share on other sites
sarogahtyp 1106 Posted March 14, 2016 1. primaryWeapon weaponDirection 2. isIRLaserOn 3. you can use intersect command handled in this thread:https://forums.bistudio.com/topic/189068-los-line-of-sight/lineIntersectsSurfaces Share this post Link to post Share on other sites
sarogahtyp 1106 Posted March 15, 2016 That should work but is not tested. Give feedback please! /* Author: Sarogahtyp (with help from BIki examples) Parameter(s): 0: [OBJECT] - Unit with IR laser designator equipped weapon Returns: [NUMBER] - distance to object or 4999 if laser disabled or not pointing to an object */ params [["_bob",objNull,[objNull]]]; //_bob = _this select 0; that was bullsh*t i thought I deleted it _maxdist = 4999; //laser designators range (lineIntersectsSurfaces has a hardcoded limit of 5000 meters) _distance = _maxdist; if (isIRLaserOn currentWeapon _bob) then { _beg = eyePos _bob; _end = (_beg vectorAdd (_bob weaponDirection currentWeapon _bob vectorMultiply _maxdist)); _array = lineIntersectsSurfaces [_beg , _end, _bob, objNull, true, 1, "GEOM","NONE"]; if((count _array) > 0) then { _endL = _array select 0; _distance = _beg distance _endL; }; }; _distance 2 Share this post Link to post Share on other sites
sjakal 13 Posted March 15, 2016 Haha, it works! Excellent answers in both posts, thanks! I can now draw a crosshair where the laser is pointing, indicating range to target. I also have some logic in place to make sure this only happens if I have tactical or VR goggles equipped, but here is the basic "Draw3D" eventhandler code: _txtXhair = ""; _posXhair = positionCameraToWorld [0, 0, 10000]; if (player isIRLaserOn currentWeapon player) then { _posLaser = eyePos player; _posXhair = _posLaser vectorAdd (player weaponDirection currentWeapon player vectorMultiply 5000); _hitLaser = lineIntersectsSurfaces [_posLaser, _posXhair, player]; if (0 < count _hitLaser) then { _posXhair = (_hitLaser select 0) select 0; _txtXhair = str(round(_posLaser distance _posXhair)); }; _posXhair = ASLToAGL _posXhair; }; drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\weapon_ca.paa", [1, 1, 1, 0.50], _posXhair, 1, 1, 0, _txtXhair, 0, 0.02, "TahomaB", "center", false];All I am missing now is regarding question 1. As far as I know eyePos returns your eyes' world position but what I need is the laser pointer or weapon muzzle's position, either in model or world space. My best bet for finding this is selectionPosition at the moment, but I struggle to find the correct selectionName matching my current weapon's muzzle.Currently the crosshair is offset slightly since the line is emitted from my character's eyes along the weapon's aim direction, instead of from the weapon's muzzle/laser emitter along its aim direction. The offset is easy to spot with NVGs at night while aiming the weapon and squeezing off a round; the crosshair is somewhat off to the side of your weapon sight reticule. Bonus points to anyone who is able to solve this final detail for question 1, then the solution will be perfect! Thanks again for the excellent example and answers already provided. Share this post Link to post Share on other sites
pedeathtrian 99 Posted March 15, 2016 sarogahtyp, Weapons have "laser pos" memory points and I guess topic starter was referring to getting its exact position. Perfectionism here =) Unfortunately I could not find a way of getting it for player's current weapon. Either use _this select 0 or params, not both. You can search for intersections of continuation of the line to go further than 5000m (if really needed). I'd say overall distance sqrt(2)*worldSize would be enough for everyone. Anyway, good work here. Share this post Link to post Share on other sites
sarogahtyp 1106 Posted March 15, 2016 "acc_pointer_IR" got it from here: primaryWeaponItems or isnt that what is wanted? Share this post Link to post Share on other sites
sjakal 13 Posted March 15, 2016 I think the problem with primaryWeaponItems or weaponAccessories is they simply return the classname of the weapon attachment, and not the model's memory point for the laser emitter. I tried this in the in-game debug console, but all I got was position [0, 0, 0]: systemChat str(player selectionPosition "acc_pointer_IR")I tried looking at Animations while in-game but as far as I know it only shows the animation names, and does not show the various memory points of my current character model. I would probably have to inspect the actual player/weapon/laser in a model tool/editor to find the memory point. Once that is found, hopefully its name can be used for the selectionPosition. Share this post Link to post Share on other sites
sarogahtyp 1106 Posted March 15, 2016 you can get the selectionName with the Dammaged EH its a return value of it. Got that Info from here: selectionPosition Share this post Link to post Share on other sites
pedeathtrian 99 Posted March 15, 2016 you can get the selectionName with the Dammaged EH its a return value of it. Got that Info from here: selectionPosition You can get selectionName for unit, i.e. some part of unit's model which was hit. I highly doubt unit can be hit in "laser pos". So the problem is to 1. get memory point "laser pos" location of weapon's model space (how to do it in game?) 2. get weapon's location (probably "Weapon" selectionName will do) and weapon's directions: direction vector (weaponDirection scripting command) and up-vector (how to do it in game?). 3. when weapon position, weapon direction and weapon up vector are acquired, you can transform "laser pos" location (or any other point) from weapon model space to unit's model space (therefore to world space too). Not sure, but "laser pos" is a place on weapon where to place attachment, not the point where laser beam hits from. One should probably analyse attachment's model too :D Share this post Link to post Share on other sites
sjakal 13 Posted March 15, 2016 Yeah, I've been struggling with exactly that. Looking at the IR laser at night on close range walls/targets, it seems the endpoint of the IR laser has no relation to where your optics or iron sights are zeroed, so I get the feeling my best bet is using the muzzle/sights/optics as point of origin instead of the laser emitter.I read somewhere that weapons or their sight attachments have an "eye" or "opticsView" memory point, but that implies I somehow need to get a reference to the weapon or attachment model in the Cfg hierarchy, starting from the player character. Alternatively I could just start the laser from the current weapon muzzle position in world or player model space, but again I struggle to find that position. Hopefully this is somewhat easier and already possible using standard OPF/ArmA commands, so I can avoid traversing Cfg/model hierarchies on subordinate weapons/attachments. The "Weapon" memory point on the player is a very good suggestion, although it seems to be quite heavily offset from where the weapon actually is. Testing this as Zeus after I kill an AI soldier to drop his weapon, I think the "Weapon" memory point is about ½m to the side of the rifle when it lies flat on the ground. Perhaps I could hardcode an offset from here into the center of the weapon. I will investigate this further tomorrow. Thanks again for the tips and help you've given already guys! This is indeed just perfectionism or nitpicking :) Share this post Link to post Share on other sites
sjakal 13 Posted March 16, 2016 Quick morning update. According to this reddit it is currently impossible to get a man's current weapon object. It is easy to find the weapon classname, but impossible to get a reference to the weapon object itself. One tedious fallback option then is traversing the configFile hierarchy for currentWeapon and the "acc_pointer_IR" laser to find their proxy/memory point offsets from the weapon/proxy point of origin, and then use their combined offsets from the player selectionPosition "Weapon". To avoid such tedium, a final alternative is simply hardcoding an offset from player selectionPosition "Weapon", but this has obvious disadvantages; you have to hardcode different offsets for each weapon in the game, and any possible modded weapons you wish to support in the future. Guess I'll have to further investigate the cfg hierarchy but I doubt it is even possible to find the proxy/memory point offsets in there. Oh well... You've gotten me very far guys, thanks! Share this post Link to post Share on other sites
pedeathtrian 99 Posted March 16, 2016 One tedious fallback option then is traversing the configFile hierarchy for currentWeapon and the "acc_pointer_IR" laser to find their proxy/memory point offsets from the weapon/proxy point of origin, and then use their combined offsets from the player selectionPosition "Weapon". Memory points' coordinates are in models, not in configs. More tedious and harder to automatize. To avoid such tedium, a final alternative is simply hardcoding an offset from player selectionPosition "Weapon", but this has obvious disadvantages; you have to hardcode different offsets for each weapon in the game, and any possible modded weapons you wish to support in the future. I considered such possibility while writing my previous post. You will need dynamic up-vector of weapon for cases when you lean right/left while shooting around the corner. If this is not taken into account, then you laser's start point will (visually) lean in opposite direction and always keep vertical (or whatever offset it will have) relative to "Weapon" selectionPosition. So yeah. Point and two (non-collinear) vectors: this is what you need to fully define 3d coordinate system (or a matrix to transform to/from). Share this post Link to post Share on other sites
sarogahtyp 1106 Posted March 16, 2016 okay, i think i cant help with the start position of that range finding thing but I ve another problem. I used sjakals script and what I dont want is that the range and the crosshair is drawn when the player is not in the sights view by clicking right mouse button. How do I check if the player uses the weapons sights? Share this post Link to post Share on other sites
sarogahtyp 1106 Posted March 16, 2016 I got it with that check: if ((player isIRLaserOn currentWeapon player) and (cameraView == "GUNNER")) then Share this post Link to post Share on other sites
sarogahtyp 1106 Posted March 16, 2016 Ok, I would say lets do a manual correction for that memory point problem. if we do a manual correction for an average weapon (average in size and IR lasers mount point) then we have a quite good solution I think. I dont know much about the different weapons in Arma 3 so I could use a hint which weapon we should take. I already began with those manual correction but its far away from being perfect: _temppos = player selectionPosition "pilot"; // thats the same as eyePos. _posLaser = AGLToASL (player modelToWorld ( [((_temppos select 0)+0.05), ((_temppos select 1) + 0.1), ((_temppos select 2) - 0.05)])); Now I ve to go to work and so I have no time to optimize it more... maybe one of u guys could. Share this post Link to post Share on other sites
sjakal 13 Posted March 16, 2016 At work myself so will follow up later today. Quick thoughts: Using "pilot" position may give issues similar to eyePos if player lowers their weapon while laser is active. The "Weapon" memory point avoids this potential issue. I also totally agree; investigating models is way too tedious so a good hardcoded default offset is the way forward, with special offsets for special weapons as needed. Thanks for the rapid responses guys! Share this post Link to post Share on other sites
sarogahtyp 1106 Posted March 16, 2016 Okay, we can start that with "Weapon" memory point even if I will not let the crosshair and range show when player is not using sights. Another thing what came in my mind is to add a laser target at end position of the IR laser. So we should implement _target = "LaserTargetW" createVehicle (getpos player); and set its pos continueously as long as the IR laser is activated. Now back to the memory point. BI is doing the same as we do with the laser itself and it is pointing always to the correct position. They must have a way to do that without the name of the memory point because every modder can name the memory points as he likes for his custom weapon but the IR laser is always at correct position, isnt it? So we have to think about how is BI doing that? Share this post Link to post Share on other sites
sarogahtyp 1106 Posted March 16, 2016 (edited) what about getPosASL nearestObject [player, "acc_pointer_IR"]; did you guys already try that? Edited March 18, 2016 by sarogahtyp Share this post Link to post Share on other sites
sjakal 13 Posted March 16, 2016 Good idea with spawning a lasertarget, and nice find on checking player is aiming! I tried some variations of nearestObject in Debug Console, sadly to no avail, always resulting in <NULL-OBJECT> most likely since the laser attachment has no logical game object but only a model. systemChat str(aimPos player nearestObject "acc_pointer_IR")So it seems hardcoded offsets are still the most valid option, but as pedeathtrian mentions we need two non-colinear and weapon-relative direction vectors to do that, and so far we only have weaponDirection. The eyeDirection vector might be non-colinear, but it is not weapon-relative. A shell casing eject direction would be a good alternative, if such is accessible via scripting commands. Oh! Or maybe a vector from "Weapon" to the "righthand" memory point since it is practically glued to the weapon at most times anyway.But yeah, the optimal solution of course is somehow reverse engineering the in-game laser beam start or end point. _posXhair = ASLToAGL _posXhair; // insert the two code lines below here _posLaser = ASLToAGL _posLaser; drawLine3D [_posLaser, _posXhair, [1,1,1,1]];PS: Add the lower two lines above to my previous code to draw the line simulating the laser beam on-screen if you have not done so already, it makes visualizing and offsetting the positions easier. Share this post Link to post Share on other sites
sarogahtyp 1106 Posted March 16, 2016 ok, i think now i have the solution. the key is not the start but the end position. we should use end = screenToWorld [0.5, 0.5]; position format is AGL but that only is useful if u forbid range finding when player is not aiming Share this post Link to post Share on other sites
sjakal 13 Posted March 16, 2016 (edited) Alright, I think I finally have SOMETHING! Try this code in place of my previous examples: //Default to 5000m in front of camera if laser is disabled _arXhair = positionCameraToWorld [0.000000, 0.000000, 5000.000000]; _arXtext = ""; _arAngle = 45; if (player isIRLaserOn currentWeapon player) then { _posXhair = AGLToASL (player modelToWorld (player selectionPosition "Weapon")); //Create the three axes from the player character model weapon memory point _right = _posXhair vectorFromTo AGLToASL (player modelToWorld (player selectionPosition "righthand")); _forward = player weaponDirection currentWeapon player; _up = _right vectorCrossProduct _forward; _right = _forward vectorCrossProduct _up; //Offset the laser start position using the three axes created above _posLaser = _posXhair; { //This default LaserOffset below seems to work OK if (isNil "LaserOffset") then { _posLaser = _posLaser vectorAdd (_x vectorMultiply ([0.700000, 0.770000, 0.100000] select _forEachIndex)); } else { _posLaser = _posLaser vectorAdd (_x vectorMultiply (LaserOffset select _forEachIndex)); //These three axis and offset drawlines can be hidden when no longer needed if (_forEachIndex == count LaserOffset - 1) then { drawLine3D [ASLToAGL _posXhair, ASLToAGL (_posXhair vectorAdd _right), [1,0,0,1]]; drawLine3D [ASLToAGL _posXhair, ASLToAGL (_posXhair vectorAdd _forward), [0,1,0,1]]; drawLine3D [ASLToAGL _posXhair, ASLToAGL (_posXhair vectorAdd _up), [0,0,1,1]]; drawLine3D [ASLToAGL _posXhair, ASLToAGL _posLaser, [1,1,0,1]]; }; }; } forEach [_right, _forward, _up]; //Find the laser end position by using a 5000m line intersect check _posXhair = _posLaser vectorAdd (_forward vectorMultiply 5000.000000); _hitLaser = lineIntersectsSurfaces [_posLaser, _posXhair, player]; if (0 < count _hitLaser) then { _arXhair = ASLToAGL ((_hitLaser select 0) select 0); _arXtext = str(round(_arXhair distance ASLToAGL _posLaser)); } else { _arXhair = ASLToAGL _posXhair; _arXtext = ""; }; _arAngle = 0; }; drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\weapon_ca.paa", [1, 1, 1, 0.5], _arXhair, 1, 1, _arAngle, _arXtext, 0, 0.02, "TahomaB", "center", false];Then go in-game, activate the weapon IR laser, and then Local Exec the following via Debug Console: LaserOffset = [0.700000, 0.770000, 0.100000]You should then see a red, green, blue and yellow guideline somewhere near your player character when in 3rd person, and your crosshair should now be roughly at where the IR laser is pointing. Using the red, green and blue guides, you can now adjust your offset in real-time via the in-game Debug Console until you are satisfied. Notice how the yellow line indicates your offset from the "Weapon" position.Granted, the axes do not align perfectly with the weapon's right and up axes, but it should still be an improvement over eyePos since that was not weapon-relative but this new position seems to follow the weapon around even when you peek around corners. Once you are satisfied the drawLine3D commands can be commented out to hide the visual guides and increase FPS slightly. Experiment as needed and please post your findings and preferred LaserOffset :) Edited March 19, 2016 by sjakal Share this post Link to post Share on other sites
sarogahtyp 1106 Posted March 17, 2016 (edited) I dont know, I m to tired to test it but here is my solution. while{true} do { while {player isIRLaserOn currentWeapon player} do { if (cameraView == "GUNNER") then { _txtXhair = ""; _posXhair = positionCameraToWorld [0, 0, 10000]; _dir = player weaponDirection (currentWeapon player); //EDIT: substituted following line as it is a better solution then // _corr = ([0.12,0.57,0.52] vectorAdd [0,0,1.5*(_dir select 2)]); _corr = [0.12,0.57,0.52 * (_dir select 2)]; _temppos = player selectionPosition "pilot"; _posLaser = AGLToASL (player modelToWorld (_temppos vectorAdd _corr)); _posXhair = _posLaser vectorAdd (_dir vectorMultiply 4999); _hitLaser = lineIntersectsSurfaces [_posLaser, _posXhair, player,objNull, true, 1, "GEOM","NONE"]; if (0 < count _hitLaser) then { _posXhair = (_hitLaser select 0) select 0; _txtXhair = str(round(_posLaser distance _posXhair)); }; _posXhair = ASLToAGL _posXhair; drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\weapon_ca.paa", [0,0.2,0,1], _posXhair, 1, 1, 0, _txtXhair, 0, 0.02, "TahomaB", "center", false]; }; sleep 0.03; }; sleep 5; }; Edited March 18, 2016 by sarogahtyp Share this post Link to post Share on other sites
sarogahtyp 1106 Posted March 17, 2016 (edited) okay, i tested both solutions a bit and it turns out they both have advantiges and disadvantages.I tested with a scope where I now define the horizontal line as x-axis and the vertical line as y-axis to let u know what i found out.I used this scope: this addPrimaryWeaponItem "optic_SOS";and that weapon: this addWeapon "arifle_MXM_F";there are markers at these lines which I used to get a distance when the crosshair reaches em. I used the inner markers for that.Your solution:crosshair reached inner x-axis marker at a distance of 7 mcrosshair reached inner y-axis marker at a distance of 10 mMy solution:crosshair reached inner x-axis marker at a distance of 130 mcrosshair reached inner y-axis marker at a distance of 9 mSo ur solution is much more precise but I ve the problem with your code that it seems to be slow. The crosshair is blinking very much at my slow PC. I tried to compensate that by retracing the crosshair between calculations and it gets a bit better but it is still blinking.EDIT: i did not test leaning, kneeling and crouching. i assume that my code should cover it cause i use eye position. i dont know if yours do. Edited March 17, 2016 by sarogahtyp Share this post Link to post Share on other sites
sarogahtyp 1106 Posted March 17, 2016 Now I substituted this line of my code: _corr = ([0.12,0.57,0.52] vectorAdd [0,0,1.5*(_dir select 2)]); with that one: _corr = [0.12,0.57,0.52 * (_dir select 2)]; and now it is as precise as your solution: crosshair reached inner x-axis marker at a distance of 9 m crosshair reached inner y-axis marker at a distance of 10 m I prefer my code now for the much better performance. Share this post Link to post Share on other sites
sarogahtyp 1106 Posted March 17, 2016 on my way to work now and i m thinking about the hard coded correction values. now i think its possible to implement an auto correction algorithm which should work with every weapon and would find better values as we are able to. i will work on it. Share this post Link to post Share on other sites