The formulas I saw for 3D trilateration were pretty complicated at first. Your idea of putting volume and spawning ship directly on the x, y, and z axis helped to greatly simplify them I think.
I think thatâs exactly what did it. Iâll admit it was unintentional though.
Sometimes coincidences give great results ^^
Okay, here is what I have found practical to use. This, once set up, can allow me to script quickly the exact location I want the camera to be with very little trial and error. Trial and error in the old way (just modifying the X, Y, X coordinates) took hours trying to script a simple scene.
I added everything @radar3301 has provided above.
I then added some code myself (disclaimer, I am not a LUA developer)
In \HomeworldRM\B8MissionMOD\leveldata\campaign\rr_oemb\m28_Return_gehenna.lua
Add Function:
function cheat_i()
print(âCamera Positionâ)
local leaderPosition = SobGroup_GetCentrePosition(âHumanPlayerSOBâ)
print(âleaderPosition = {ââŚleaderPosition[1]âŚ", ââŚleaderPosition[2]âŚâ, ââŚleaderPosition[3]âŚâ},")
local pos = Camera_GetPosition();
print(pos[âXâ], pos[âYâ], pos[âZâ])
end
And in the function: function Rule_Init()
UI_BindKeyEvent( IKEY, âcheat_iâ )
Summary
Basically, in making scenes, I use the AddCamera to control where the player is looking. AddCamera requires two sets of XYZ coordinates, first set being where the camera will look and the second set of the base point of the camera.
e.g.
addCamera(âcamera1â, {0.000000, 0.000000, 0.000000}, {-252.000000, 1548.000000, 5791.000000})
In game, I select an object (ship, asteroid, etc). I move the screen to position how I want the player to see it. then I press âiâ.
Using the code in my example:
local leaderPosition = SobGroup_GetCentrePosition(âHumanPlayerSOBâ)
print(âleaderPosition = {ââŚleaderPosition[1]âŚ", ââŚleaderPosition[2]âŚâ, ââŚleaderPosition[3]âŚâ},")
Returns this in the HwRM.log:
leaderPosition = {720.3656005859375, 828.7918090820313, 968.1722412109375},
Since in most scenes the player is going to look at something, I use the âsomethingâ to provide the coordinates of WHERE the player is looking.
Then using @radar3301 code, which is activated by me calling;
local pos = Camera_GetPosition();
print(pos[âXâ], pos[âYâ], pos[âZâ])
Returns this in the HwRM.log:
-252.1182701686859
1543.764143411255
5792.635323712289
This is the BASE POINT.
I copy those two prints from the log into the addCamera in my m28_Return_gehenna.level file. And I now have a camera starting point that will start near exactly where I hit âiâ in my game.
WISHLIST to make this even easier.
My first PRINT statement is a near perfect copy-paste from log to level file. I only have to trim the extra digits past 5. However @radar3301 function returned values printed are on 3 lines and I have to massage the data more to get into the AddCamera. I have been trying to do string manipulation in order to automatically scrape the log and write the values in the correct syntax for an easier copy-paste but, and with my limited LUA knowledge, I have not been successful. Print looks to be more a simple function to view results quickly. I can do this outside of LUA with C#, PowerShell, etc but that requires using another tool to do something that may be able to be inherent in this function on its own?
Basically it would be nice to turn this:
Camera Position
leaderPosition = {720.3656005859375, 828.7918090820313, 968.1722412109375},
-252.11827016868591543.764143411255
5792.635323712289
into this:
addCamera(âcamera1â, {720.365600, 828.79180, 968.17224}, {-252.118270, 1543.764143, 5792.635323})
It is a small thing⌠but as a programmer I am always looking for ways to automate to make things easier. 
@BitVenom I am also curious, the camActions you showed us in this post:
Is it possible to use that current functionality to control camera movements for a Mission Map? Or is CamAction just a tool for making videos?
Currently in my attempts to make a mission map, when I want to make a âsceneâ for the player using the in game units I just use normal HW2 scripting reference to script in lua.
local pos = Camera_GetPosition()
print(pos["X"], pos["Y"], pos["Z"])
should be
local pos = Camera_GetPosition()
print("campos = {" .. pos.X .. ", " .. pos.Y .. ", " .. pos.Z .. "}")
to get it to print on one line.
Also, not sure if the (duh, it is. Itâs used in the ATI_AddString function in camerautils.lua [facepalm]), this will help you immensely:format library function is available in GameRules, but if it is
local pos = Camera_GetPosition()
print(format("campos = {%0.5d, %0.5d, %0.5d}", pos.X, pos.Y, pos.Z))
(And yes, you can reference named table keys like that
).
EDIT:
Even better:
local dst = SobGroup_GetCentrePosition("HumanPlayerSOB")
local src = Camera_GetPosition()
print("addCamera(\"camera1\", " .. format("{%f, %f, %f}, {%f, %f, %f}", dst[1], dst[2], dst[3], src.X, src.Y, src.Z) .. ")\n")
EDIT:
Fixed print code.
I didnât know you could use format() with several variables in one call, thatâs good to know !
Thatâs the whole point of format. 
I fixed the addCamera print line above, reposted here:
local dst = SobGroup_GetCentrePosition("HumanPlayerSOB")
local src = Camera_GetPosition()
print("addCamera(\"camera1\", " .. format("{%f, %f, %f}, {%f, %f, %f}", dst[1], dst[2], dst[3], src.X, src.Y, src.Z) .. ")\n")
Ship sway actually doesnât affect the calculations (even though ships do sway). I printed out the values of the positions of the probes used as âanchorsâ, and they donât change. Iâm now of the opinion that the camera sways slightly. I did a quick test using a KeyBind (yes, they work, even while paused), and without moving the camera, got several differing values (I think itâs an âelasticâ camera). Again though:
Ran into a problem trying to get my invisible ship to work, which did work in my previous mod. I feel the error message is telling me what to do; however, i do not work with ships much and do not want to risk mucking things up.
here is the error message, âError in Ship/Missile:âHGN_INVISIBLETARGETâ: The Thruster brake time needs to be smaller than the acceleration time!â
What value does I need to tweak in the ship? Here is my ship:
Blockquote
NewShipType = StartShipConfig()
NewShipType.displayedName=âTargetâ
NewShipType.sobDescription=âTarget Pointâ
NewShipType.maxhealth=getShipNum(NewShipType, âmaxhealthâ, 90000)
NewShipType.regentime=0
NewShipType.minRegenTime=0
NewShipType.sideArmourDamage = getShipNum(NewShipType, âsideArmourDamageâ, 1.0)
NewShipType.rearArmourDamage = getShipNum(NewShipType, ârearArmourDamageâ, 1.0)
setTacticsMults(NewShipType, âMAXSPEEDâ, 1.0, 1.10, 1.0)
setTacticsMults(NewShipType, âENGINEACCELâ, 1.20, 0.80, 1.0)
setTacticsMults(NewShipType, âENGINEBRAKEâ, 1.0, 1.0, 1.0)
setTacticsMults(NewShipType, âTHRUSTERâ, 1.0, 1.0, 1.0)
setTacticsMults(NewShipType, âTHRUSTERACCELâ, 1.20, 0.80, 1.0)
setTacticsMults(NewShipType, âTHRUSTERBRAKEâ, 1.0, 1.0, 1.0)
setTacticsMults(NewShipType, âROTATIONâ, 1.0, 1.10, 1.0)
setTacticsMults(NewShipType, âROTATIONACCELâ, 1.0, 1.10, 1.0)
setTacticsMults(NewShipType, âROTATIONBRAKEâ, 1.0, 1.0, 1.0)
setTacticsMults(NewShipType, âWEAPONACCURACYâ, 1.0, 1.0, 1.0)
setTacticsMults(NewShipType, âWEAPONDAMAGEâ, 1.20, 1.0, 1.0)
setTacticsMults(NewShipType, âBULLETSPEEDâ, 1.15, 1.0, 1.0)
setTacticsMults(NewShipType, âDAMAGEAPPLIEDâ, 1.10, 0.90, 1.0)
setTacticsMults(NewShipType, âFIRERATEâ, 1.0, 1.25, 1.0)
setSpeedvsAccuracyApplied(NewShipType, 100.0, 5.0, 250, 1.0, 409, 1.0, 563, 0.90)
NewShipType.isTransferable=1
NewShipType.SquadronSize=getShipNum(NewShipType, âSquadronSizeâ, 1)
NewShipType.buildBatch=getShipNum(NewShipType, âbuildBatchâ, 1)
NewShipType.formationSpacing=30
NewShipType.batchFormation=âBatch_deltaâ
NewShipType.defaultROE=âDefensiveâ
NewShipType.defaultStance=âAggressiveâ
NewShipType.holdSlots=2
NewShipType.mass=10
NewShipType.collisionMultiplier=1
NewShipType.thrusterMaxSpeed=1
NewShipType.mainEngineMaxSpeed=1
NewShipType.rotationMaxSpeed=1
NewShipType.thrusterAccelTime=1
NewShipType.thrusterBrakeTime=2
NewShipType.mainEngineAccelTime=1
NewShipType.mainEngineBrakeTime=2
NewShipType.rotationAccelTime=0.5
NewShipType.rotationBrakeTime=0.3
NewShipType.thrusterUsage=0.25
NewShipType.accelerationAngle=30
NewShipType.mirrorAngle=30
NewShipType.secondaryTurnAngle=90
NewShipType.maxBankingAmount=85
NewShipType.descendPitch=0
NewShipType.goalReachEpsilon=5
NewShipType.slideMoveRange=0
NewShipType.controllerType=âShipâ
NewShipType.tumbleStaticX=10
NewShipType.tumbleStaticY=20
NewShipType.tumbleStaticZ=5
NewShipType.tumbleDynamicX=100
NewShipType.tumbleDynamicY=200
NewShipType.tumbleDynamicZ=50
NewShipType.tumbleSpecialDynamicX=600
NewShipType.tumbleSpecialDynamicY=800
NewShipType.tumbleSpecialDynamicZ=500
NewShipType.relativeMoveFactor=6
NewShipType.swayUpdateTime=2
NewShipType.swayOffsetRandomX=10
NewShipType.swayOffsetRandomY=10
NewShipType.swayOffsetRandomZ=10
NewShipType.swayBobbingFactor=0.05
NewShipType.swayRotateFactor=0.1
NewShipType.dustCloudDamageTime=100
NewShipType.nebulaDamageTime=20
NewShipType.MinimalFamilyToFindPathAround=âSuperCapâ
NewShipType.mirrorAboveManeuver=âImmelMann_speedy, OneEightyDegRightTurn, OneEightyDegLeftTurn, ImmelMann_speedy, ImmelMann_speedy, ImmelMann_speedyâ
NewShipType.mirrorBelowManeuver=âSplit_S_speedy, OneEightyDegRightTurn, OneEightyDegLeftTurn, Split_S_speedy, Split_S_speedy, Split_S_speedyâ
NewShipType.specialTurnLeftManeuver=âNinetyDegLeftTurn, None, Noneâ
NewShipType.specialTurnRightManeuver=âNinetyDegRightTurn, None, Noneâ
NewShipType.BuildFamily=âSuperCap_Hgnâ
NewShipType.AttackFamily=âBigCapitalShipâ
NewShipType.DockFamily=âCarrierâ
NewShipType.AvoidanceFamily=âSuperCapâ
NewShipType.DisplayFamily=âCapitalâ
NewShipType.AutoFormationFamily=âCapShipâ
NewShipType.CollisionFamily=âSmallâ
NewShipType.ArmourFamily=getShipStr(NewShipType, âArmourFamilyâ, âUnarmouredâ)
setSupplyValue(NewShipType, âCapitalâ, 1.0)
setSupplyValue(NewShipType, âCarrierâ, 1.0)
NewShipType.fighterValue=1
NewShipType.corvetteValue=0
NewShipType.frigateValue=0
NewShipType.neutralValue=0
NewShipType.antiFighterValue=0
NewShipType.antiCorvetteValue=0
NewShipType.antiFrigateValue=0
NewShipType.totalValue=1
NewShipType.buildCost=300
NewShipType.buildTime=20
NewShipType.buildPriorityOrder=10
NewShipType.retaliationRange=4800
NewShipType.retaliationDistanceFromGoal=160
NewShipType.visualRange=1500
NewShipType.prmSensorRange=9000
NewShipType.secSensorRange=11000
NewShipType.detectionStrength=1
NewShipType.TOScale=1
NewShipType.TODistanceFade0=7000
NewShipType.TODistanceDisappear0=5000
NewShipType.TODistanceFade1=2500
NewShipType.TODistanceDisappear1=2000
NewShipType.TODistanceFade2=12000
NewShipType.TODistanceDisappear2=35000
NewShipType.TOGroupScale=1
NewShipType.TOGroupMergeSize=0
NewShipType.mouseOverMinFadeSize=0.045
NewShipType.mouseOverMaxFadeSize=0.1
NewShipType.healthBarStyle=0
NewShipType.nlips=0.0008
NewShipType.nlipsRange=6000
NewShipType.nlipsFar=0.0003
NewShipType.nlipsFarRange=10000
NewShipType.SMRepresentation=âHardDotâ
NewShipType.meshRenderLimit=11000
NewShipType.dotRenderLimit=10
NewShipType.visibleInSecondary=0
NewShipType.minLOD=0.25
NewShipType.goblinsStartFade=210
NewShipType.goblinsOff=210
âNewShipType.upLOD=700
âNewShipType.downLOD=500
NewShipType.minimumZoomFactor=0.68
NewShipType.selectionLimit=150000
NewShipType.preciseATILimit=0
NewShipType.selectionPriority=75
NewShipType.militaryUnit=1
addAbility(NewShipType,âMoveCommandâ,1,0);
addAbility(NewShipType,âCanDockâ,1,1);
NewShipType.dockTimeBetweenTwoFormations=0.5
NewShipType.dockTimeBeforeStart=0.5
NewShipType.dockNrOfShipsInDockFormation=1
NewShipType.dockFormation=âdocklineâ
NewShipType.queueFormation=ân_deltaâ
NewShipType.ignoreRaceWhenDocking=0
addAbility(NewShipType,âCanLaunchâ);
addAbility(NewShipType, âHyperspaceInhibitorAbilityâ, 1, 12000);
NewShipType.launchTimeBetweenTwoFormations=0.5
NewShipType.launchTimeBeforeStart=1.5
NewShipType.launchNrOfShipsInDockFormation=1
NewShipType.launchFormation=ân_deltaâ
addAbility(NewShipType,âParadeCommandâ,1);
addAbility(NewShipType,âWaypointMoveâ);
addAbility(NewShipType,âCanAttackâ,1,2,1,0,0.35,1,âFighter, Fighter_hw1, Corvette, Corvette_hw1, Frigate, SmallCapitalShip, BigCapitalShip, Mothershipâ,âFlyBy_Interceptor_vs_Frigateâ,
{Fighter=âFighter_vs_Fighterâ},
{Fighter_hw1=âFighter_vs_Fighterâ},
{Corvette=âFighter_vs_Corvetteâ},
{Corvette_hw1=âFighter_vs_Corvetteâ},
{Frigate=âFighter_vs_Frigateâ},
{SubSystem=âTopAttack_Interceptor_vs_Subsystemâ},
{SmallCapitalShip=âFighter_vs_CapShipâ},
{BigCapitalShip=âFighter_vs_CapShipâ},
{Mothership=âFighter_vs_Mothershipâ},
{ResourceLarge=âFighter_vs_ResourceLargeâ});
addAbility(NewShipType,âGuardCommandâ,1,3000,500);
addAbility(NewShipType,âHyperspaceViaGateCommandâ,1,3,1,0.3);
addAbility(NewShipType,âSensorPingâ,0,1,10,2.5);
addAbility(NewShipType,âSpecialAttackâ,0,âEMPâ);
addAbility(NewShipType,âRetireAbilityâ,1,0);
LoadModel(NewShipType,1);
âStartShipWeaponConfig(NewShipType,âHgn_Peashooterâ,âWeapon_Autogunâ,âWeapon_Autogunâ);
âStartShipWeaponConfig(NewShipType,âHgn_SmallEMPâ,âWeapon_Autogunâ,âFireâ);
NewShipType.battleScarCoverage=0
NewShipType.sobDieTime=2
NewShipType.sobSpecialDieTime=2
NewShipType.specialDeathSpeed=40
NewShipType.chanceOfSpecialDeath=0.5
NewShipType.deadSobFadeTime=1
âsetEngineTrail(NewShipType,0,5,âtrail_ribbon.tgaâ,0.001,0.5,0.025,8);
âsetEngineBurn(NewShipType,15,0.5,1,15,0,0.7,0.1,25);
loadShipPatchList(NewShipType,âdata:sound/sfx/ship/Hiigaran/Fighter/â,0,âHScoutEngâ,"");
addShield(NewShipType,âEMPâ,100,20);
NewShipType.minFalloffDamageDist=15
NewShipType.maxFalloffDamageDist=153
NewShipType.maxFalloffScuttleDamageDist=156
NewShipType.explosiveScuttleDamageOnDeath=15
NewShipType.maxFalloffForce=500*10
NewShipType.explosiveDamageOnDeath=275
NewShipType.radiusDamageEvadeMod=1.1
NewShipType.hideNormalAttackUICooldown=1
NewShipType.agileFlight=1
NewShipType.homingDistance=2000
NewShipType.homingDelay=0.5
NewShipType.strikeGroupSpeed=5000
NewShipType.canSurround=0
Blockquote
Problem might be here. I donât know what exactly the numbers represent however.
setTacticsMults(NewShipType, âTHRUSTERACCELâ, 1.20, 0.80, 1.0)
setTacticsMults(NewShipType, âTHRUSTERBRAKEâ, 1.0, 1.0, 1.0)
Thatâs it, thrusterBrakeTime needs to be smaller than thrusterAccelTime
I suppose otherwise your ship might end up going backwardsâŚ