Author Topic: atomspheric flight  (Read 7083 times)

0 Members and 1 Guest are viewing this topic.

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
ive been awake for like 2 days now developing this thing. i took a look at my old newtonian script, which had a bug that maybe broke colision detection. i was tinkering trying to fix it, i was unable to, but i thought it would be cool to try out some other features. started by adding lift and gravity forces in a hackish way, i didnt like it and got to thinking about adding drag. fortunately the drag equation was simple enough for me to handle. and i plugged it into the game without much hassle. it handled a tad more realistically (for atmo flight).

since there are 4 forces of flight, thrust, drag, lift and weight. i figured i was half way to making freeatmo1 :D. gravity was easy, i looked it up and realized i just needed to plug the ships mass into it to make it work more realistically. i spent most of today working on lift and tweaking vars. lift still isnt perfect but it works. theres something quirky about the direction of the force vector. according to nasa, lift is a force that needs to be perpendicular to the airflow and in the lift direction of the wing. however the function returns a number, and not a vector. needless to say i couldnt find an easy way to do this. multiplying the number by a ship's up vector didnt work to well, and wasnt perpendicular to airflow. tried using a matrix in 10 different ways. tried a cross product which got the best result, but the thing tends to wander and isnt always prependicular to airflow. maybe one of the physics nuts can look at it.

the script is simple, load a mission with some stationary stuff in it, maybe throw in a skybox or some terrain for orientation purposes (stay upright or you will fall like a brick, dont pull up too fast or you will stall). the physics vars are heavily commented to make tweaking a sinch. its set up to handle a ulysses right now. but any ship will work. only player ship gets affected so dont bother thowing in any bad guys. switch to external view to see the force vectors. ive also thrown airspeed and altitude indicators in as well so you can monitor your climb. have fun!

Code: [Select]
#Global Hooks
$GameInit:
[
--[[=============================]]--
--[[======= function defs =======]]--
--[[=============================]]--

setscreenvars = function() --scalers and constants for multi res support
local w = gr.getScreenWidth()
local h = gr.getScreenHeight()
local cx = w/2
local cy = h/2
local wf = 0
local hf = 0
local awh = 0
local hires = false

if w >= 1024 then
wf = w / 1024
hf = h / 768
awh = (wf + hf) / 2
hires = true
else
wf = w / 640
hf = h / 480
awh = ((wf + hf) / 2) * 0.625
hires = false
end

return w,h,cx,cy,wf,hf,awh,hires
end

mousejoy = function() --mousejoy function, returns a value from -1 to 1 depending on the mouse's position
local X = io.getMouseX()
local Y = io.getMouseY()

if hires then
X = (X / 511.5) - 1
Y = (Y / 383.5) - 1
else
X = (X / 319.5) - 1
Y = (Y / 239.5) - 1
end

return X,Y
end

round = function(number) --rounds to nearest whole number, for some stupid reason, lua doesnt have this function
local W,F = math.modf(number)
if F < 0 then
if F <= -0.5 then W = W - 1 end
else
if F >= 0.5 then W = W + 1 end
end

return W
end

prograderet = function(x,y,vel)
x, y = x*wf, y*hf --round theese, our vector gets jumpy

gr.setColor(72,192,72,222)

gr.drawGradientLine(x + (12*awh), y + (12*awh), x + (6*awh), y + (6*awh) )
gr.drawGradientLine(x - (12*awh), y - (12*awh), x - (6*awh), y - (6*awh) )
gr.drawGradientLine(x - (12*awh), y + (12*awh), x - (6*awh), y + (6*awh) )
gr.drawGradientLine(x + (12*awh), y - (12*awh), x + (6*awh), y - (6*awh) )

vel = tostring(vel)

gr.setColor(128,192,128,222)
gr.drawString(vel, x - (gr.getStringWidth(vel) / 2), y - (2*awh) )
end

w,h,cx,cy,wf,hf,awh,hires = setscreenvars()

--[[=============================]]--
--[[======= physics specs =======]]--
--[[=============================]]--
--theese are for the ulysses, i picked this fighter because its essentially a flying wing.
--eventually i plan on making theese loadable via text file. yweek theese abit, try to
--make other profiles for other ships


--max thrust values in newtons, will load from file per ship eventually
--ramp the up thrust for ships without good wings will fly sorta like a helicopter
fd_thrust, rv_thrust, up_thrust, dn_thrust, lf_thrust, rt_thrust = 24000, 6000, 8000, 4000, 4000, 4000
--mass in kg
shp_mass = 5000
--cross-sections for drag area computation, area in square meters
--to figure these out, export the ship to max and maintain scale!. choose an orthagonal view
--for the plane you wish to work on first. top is xz, front is xy, and side is yz. flatten the
--ship to a plane using scale. if youre working on the xz plane you want to flatten by setting
--y to 0%. in other words scale the axis not in plane. then use the poly select tool (with ignore
--backfacing enabled) and select all visible polies and hit del. this leaves a flat cross
--section on the other side that you can measure. open the utilities panel and select measure.
--grab the number from the surface area field. hit undo a few times to restore your model.
--repeat for the other 2 planes.
xy_area = 27.28
xz_area = 104.77
yz_area = 55.09
--drag coefficient
drag_ce = 0.020 --about that of a cessna, more = less streamlined, a brick had a dce of about 2
--lift coefficient
--be careful with lift values, too much will throw you out of the level
lift_ce = 0.06 --a fighter jet uses about 0.3, but this is as high as i dare go more = more lift
--wing area
--sorta guesstimate this, its gonna be a number between 0 and xz_area. more = more lift
wing_area = 95 --the whole ship is a wing

--enviroment specs
--gravitational force per kg
--im using planer gravity right now, but may implement spherical gravity later on
grav_force = 9.78033 --earth grav
--atmospheric pressure kg/m^3
--eventually il throw in barametrics to simulate diferent density at diverent altitudes
atmo_pres = 1.293 --earth atmo at ground level at 0c
--no more physics vars to tweek, maybe more next time

wvel = ba.createVector(0,0,0)

]
$simulation:
[

player = mn.Ships["Alpha 1"]

--first lets do thrust, its longer due to tweaked input code
if player:isValid() then
tvec = ba.createVector(0,0,0)
--tvec.x = player.Physics.SideThrust
--tvec.y = player.Physics.VerticalThrust
tvec.x, tvec.y = mousejoy() --more usefull cause you can set lift to an arbitrary amount
tvec.y = -tvec.y
tvec.z = player.Physics.ForwardThrust

if tvec.x > 0 then
tvec.x = tvec.x * lf_thrust
else
tvec.x = tvec.x * rt_thrust
end

if tvec.y > 0 then
tvec.y = tvec.y * up_thrust
else
tvec.y = tvec.y * dn_thrust
end

if tvec.z > 0 then
tvec.z = tvec.z * fd_thrust
else
tvec.z = tvec.z * rv_thrust
end

tvec = player.Orientation:unrotateVector(tvec) --convert local vector to world space

--first compute some important data
local wvel_len = wvel:getMagnitude()
local wvel_sqrd = wvel_len * wvel_len
if wvel_len > 0 then wvel_len_f = 1 / wvel_len else wvel_len_f = 1 end --avoid div by zero error
local wvel_norm = wvel * wvel_len_f
local wvel_norm_rot = player.Orientation:rotateVector(wvel_norm)

--lets do drag, figure out how much area is hitting the wind
--scale cross sections by components of the normalized, rotated velocity vector
local area = xy_area * math.abs(wvel_norm_rot.z) +
xz_area * math.abs(wvel_norm_rot.y) +
yz_area * math.abs(wvel_norm_rot.x)
--lets plug the drag equasion
local drag = drag_ce * area * 0.5 * atmo_pres * wvel_sqrd
dvec = (wvel_norm * -1) * drag

--now for lift
local lift = lift_ce * wing_area * 0.5 * atmo_pres * wvel_sqrd
lvec = wvel_norm:getCrossProduct(player.Orientation:unrotateVector(ba.createVector(1, 0, 0)))
lvec = lvec * lift

--gravity is really easy
gvec = ba.createVector(0,-grav_force ,0) * shp_mass

--add em up to get our total force vector
fvec = tvec + dvec + lvec + gvec

--factor in mass
local massfactor = 1 / shp_mass
fvec2 = fvec * massfactor

--add to velocity
wvel = wvel + fvec2

--adjust for frametime
local wvel_timescaled = wvel * ba.getFrametime()

--use it
Vx,Vy = (player.Position + wvel):getScreenCoords()
velmag = wvel:getMagnitude()
player.Position = player.Position + wvel_timescaled
player.Physics.Velocity = wvel
end

]
$Hud:
[

if player:isValid() then
gr.setColor(255,0,0,255)
gr.drawString("Thrust:   "..math.ceil(tvec.x).." ' "..math.ceil(tvec.y).." ' "..math.ceil(tvec.z))
gr.setColor(0,255,0,255)
gr.drawString("Drag:     "..math.ceil(dvec.x).." ' "..math.ceil(dvec.y).." ' "..math.ceil(dvec.z))
gr.setColor(0,0,255,255)
gr.drawString("Lift:     "..math.ceil(lvec.x).." ' "..math.ceil(lvec.y).." ' "..math.ceil(lvec.z))
gr.setColor(255,255,0,255)
gr.drawString("Weight:   "..math.ceil(gvec.x).." ' "..math.ceil(gvec.y).." ' "..math.ceil(gvec.z))
gr.setColor(0,255,255,255)
gr.drawString("Total:    "..math.ceil(fvec.x).." ' "..math.ceil(fvec.y).." ' "..math.ceil(fvec.z))
gr.drawCircle(5, io.getMouseX()*wf, io.getMouseY()*hf)
gr.setColor(0,0,0,255)
gr.drawString("Altitude: "..math.ceil(player.Position.y + 50000))
gr.drawString("Airspeed: "..math.ceil(wvel:getMagnitude()))

local X,Y = player.Position:getScreenCoords()
if X then
X,Y=X*wf,Y*hf
local XX,YY = (player.Position + (tvec*0.001)):getScreenCoords()
gr.setColor(255,0,0,255)
if XX then gr.drawLine(X,Y,XX*wf,YY*hf) end
XX,YY = (player.Position + (dvec*0.001)):getScreenCoords()
gr.setColor(0,255,0,255)
if XX then gr.drawLine(X,Y,XX*wf,YY*hf) end
XX,YY = (player.Position + (lvec*0.001)):getScreenCoords()
gr.setColor(0,0,255,255)
if XX then gr.drawLine(X,Y,XX*wf,YY*hf) end
XX,YY = (player.Position + (gvec*0.001)):getScreenCoords()
gr.setColor(255,255,0,255)
if XX then gr.drawLine(X,Y,XX*wf,YY*hf) end
XX,YY = (player.Position + (fvec*0.001)):getScreenCoords()
gr.setColor(255,255,255,255)
if XX then gr.drawLine(X,Y,XX*wf,YY*hf) end
end

if Vx then prograderet( Vx, Vy, round(velmag) ) end
end

]
#End
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline WMCoolmon

  • Purveyor of space crack
  • 213
It seemed a little weird. I tried using an Orion as a point of reference, and noted collision didn't work. I also had trouble diving - it seemed like I continued getting lift even when I was pointed down.

Also to round a number you should be able to do math.floor(n+0.5)

Very nice though, this could get very interesting. :D
-C

 

Offline Wanderer

  • Wiki Warrior
  • 211
  • Mostly harmless
If you want to keep collision detection working then for heavens sake do not use position data.

Its the exact same reason why i had to implement velocity based barriers to the corridor mode.

Hmmm...
Also is the lift (as a force pointing upwards) 'attenuated' with the ships orientation?
And hmm.. have you given any thoughts about using or setting up terminal velocity (though that would also need to be attenuated with ships orientation...)?
Do not meddle in the affairs of coders for they are soggy and hard to light

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
one of the reaons i tweak position data direactl is cause the gamev
It seemed a little weird. I tried using an Orion as a point of reference, and noted collision didn't work. I also had trouble diving - it seemed like I continued getting lift even when I was pointed down.

Also to round a number you should be able to do math.floor(n+0.5)

Very nice though, this could get very interesting. :D

that round func is old, most of the timei just use ceil. its probly lrft over from my old newtonian script. i expected colisions to be borked, as im still hacking position data. wvel is a valid replacement velocity though. i just need a way to tell freespace not to screw with my velocity. i tried using the on frame state hook and it worked about the same way. i eventually said **** it, im uncommenting the hack.

If you want to keep collision detection working then for heavens sake do not use position data.

Its the exact same reason why i had to implement velocity based barriers to the corridor mode.

Hmmm...
Also is the lift (as a force pointing upwards) 'attenuated' with the ships orientation?
And hmm.. have you given any thoughts about using or setting up terminal velocity (though that would also need to be attenuated with ships orientation...)?

terminal velocity seems to work as a product of the drag function. the drag force is fairly accurate. it will be even more accurate when i account for barometrics and lift induced drag.

part of the drag equation needs to know how much surface area is exposed to flow. i calculate that by rotating a normalized velocity vector to model space. i use that vector's individual components as scalers. the z axis scales the frontal area, the y axis the top down area, and x scales side area. i sum the result to get a rough approximation of how much surface area the airflow must interact with. drag_ce is the co-efficient, a  magic number which covers all the stuff tht needs t be determined experimentally. but in practice a blunt object has a higher value, small numbers are more streamlined. so a cessna is about 0.028, and a borg cube would be > 1 or more around 2.

this is only a subsonic equation however. for supersonic flight, you need to account for shock forces. should allow an adama manuver at least :D

lift still dont work right. the force is applied in the wrong direction first of all. lift force is apllied along the cross product of velocity and a world space side vector. lift seems to be all over the place. i tried simply multiplying lift by normalized velocity, and flipping z and y. but that didnt work either. im also seeing excessive horizontal component. aoa needs to be accounted for. if you try to fly straight up, instead of stalling, you just sorta hover there and climb slowly, which shouldnt be possible considering how little thrus im using. fighter jets produce thrust in terms oof hundreds of thousands of newtons. a mere 32000 newtons shouldnt be capable of that.  im probibly gonna use a world space velocity normal as a scaler again, seemed to work well for drag.
« Last Edit: December 15, 2007, 05:38:25 am by Nuke »
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline Wanderer

  • Wiki Warrior
  • 211
  • Mostly harmless
one of the reaons i tweak position data direactl is cause the gamev
Yes, but still it breaks stuff and there is no way of avoiding it.
Do not meddle in the affairs of coders for they are soggy and hard to light

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
well i got lift to work, sorta. it now can take angle of attack into account. though im not sure how accurate my aoa value is. its sorta hacked in there. the flight model is sorta acting like a flight model now. i switched the physics vars over to the perseus, got rid of the reverse, vertical and lateral thrust forces, as they were  throwing everything off, they can easily be turned back on once the flight model improves.

im still experiencing alot of horizontal lift component. the ship handles more like a helicopter than an airplane. the flight model is also lift happy. that ****ed up yaw axis that freespace uses gets really annoying here. i tried to remove it with scripting, but that didnt work. i know the wing commander people want that gone. not only does it interfere with flight as it is, but when i go to implement newtonian rotations and control surfaces, i will not be able to get axis data independant of eachother. when i check rotational velocity desired, any desired yaw from the yaw axis will also copy itself to the bank axis. i might just assign yaw to a mouse axis and take bank from the yaw axis. this is ok because i usually play flight sims more comfortably with roll on the x axis.

also added some standard aviation gauges to the data printout, suck as airspeed, vertical speed, and angle of attack. also im still waiting for a certain resident finnish physics nut to correct my physics errors :D

Code: [Select]
#Global Hooks
$GameInit:
[
--[[=============================]]--
--[[======= function defs =======]]--
--[[=============================]]--

setscreenvars = function() --scalers and constants for multi res support
local w = gr.getScreenWidth()
local h = gr.getScreenHeight()
local cx = w/2
local cy = h/2
local wf = 0
local hf = 0
local awh = 0
local hires = false

if w >= 1024 then
wf = w / 1024
hf = h / 768
awh = (wf + hf) / 2
hires = true
else
wf = w / 640
hf = h / 480
awh = ((wf + hf) / 2) * 0.625
hires = false
end

return w,h,cx,cy,wf,hf,awh,hires
end

normalize = function(v)
vlen = v:getMagnitude()
if vlen > 0 then vlen = 1 / vlen else vlen = 1 end
return v * vlen
end

mousejoy = function() --mousejoy function, returns a value from -1 to 1 depending on the mouse's position
local X = io.getMouseX()
local Y = io.getMouseY()

if hires then
X = (X / 511.5) - 1
Y = (Y / 383.5) - 1
else
X = (X / 319.5) - 1
Y = (Y / 239.5) - 1
end

return X,Y
end

prograderet = function(x,y,vel)
x, y = x*wf, y*hf --round theese, our vector gets jumpy

gr.setColor(72,192,72,222)

gr.drawGradientLine(x + (12*awh), y + (12*awh), x + (6*awh), y + (6*awh) )
gr.drawGradientLine(x - (12*awh), y - (12*awh), x - (6*awh), y - (6*awh) )
gr.drawGradientLine(x - (12*awh), y + (12*awh), x - (6*awh), y + (6*awh) )
gr.drawGradientLine(x + (12*awh), y - (12*awh), x + (6*awh), y - (6*awh) )

vel = tostring(vel)

gr.setColor(128,192,128,222)
gr.drawString(vel, x - (gr.getStringWidth(vel) / 2), y - (2*awh) )
end

w,h,cx,cy,wf,hf,awh,hires = setscreenvars()

--[[=============================]]--
--[[======= physics specs =======]]--
--[[=============================]]--
--theese are for the ulysses, i picked this fighter because its essentially a flying wing.
--eventually i plan on making theese loadable via text file. yweek theese abit, try to
--make other profiles for other ships


--max thrust values in newtons, will load from file per ship eventually
--ramp the up thrust for ships without good wings will fly sorta like a helicopter
--fd_thrust, rv_thrust, up_thrust, dn_thrust, lf_thrust, rt_thrust = 24000, 6000, 8000, 4000, 4000, 4000
--mass in kg
--shp_mass = 5000
--cross-sections for drag area computation, area in square meters
--to figure these out, export the ship to max and maintain scale!. choose an orthagonal view
--for the plane you wish to work on first. top is xz, front is xy, and side is yz. flatten the
--ship to a plane using scale. if youre working on the xz plane you want to flatten by setting
--y to 0%. in other words scale the axis not in plane. then use the poly select tool (with ignore
--backfacing enabled) and select all visible polies and hit del. this leaves a flat cross
--section on the other side that you can measure. open the utilities panel and select measure.
--grab the number from the surface area field. hit undo a few times to restore your model.
--repeat for the other 2 planes.
--xy_area = 27.28 --ulysses
--xz_area = 104.77
--yz_area = 55.09
--drag coefficient
--drag_ce = 0.020 --about that of a cessna, more = less streamlined, a brick had a dce of about 2
--lift coefficient
--be careful with lift values, too much will throw you out of the level
--lift_ce = 0.06 --a fighter jet uses about 0.3, but this is as high as i dare go more = more lift
--wing area
--sorta guesstimate this, its gonna be a number between 0 and xz_area. more = more lift
--wing_area = 95 --the whole ship is a wing

--enviroment specs
--gravitational force per kg
--im using planer gravity right now, but may implement spherical gravity later on
grav_force = 9.78033 --earth grav
--atmospheric pressure kg/m^3
--eventually il throw in barametrics to simulate diferent density at diverent altitudes
atmo_pres = 1.293 --earth atmo at ground level at 0c
--no more physics vars to tweek, maybe more next time

--pegasus
fd_thrust, rv_thrust, up_thrust, dn_thrust, lf_thrust, rt_thrust = 80000, 0, 0, 0, 0, 0
shp_mass = 12000
xy_area = 30.68
xz_area = 158.51
yz_area = 65.76
drag_ce = 0.035
lift_ce = 0.02
wing_area = 120

wvel = ba.createVector(0,0,0)

]
$simulation:
[

player = mn.Ships["Alpha 1"]

--first lets do thrust, its longer due to tweaked input code
if player:isValid() then
tvec = ba.createVector(0,0,0)
--tvec.x = player.Physics.SideThrust
--tvec.y = player.Physics.VerticalThrust
tvec.x, tvec.y = mousejoy() --more usefull cause you can set lift to an arbitrary amount
tvec.y = -tvec.y
tvec.z = player.Physics.ForwardThrust

if tvec.x > 0 then
tvec.x = tvec.x * lf_thrust
else
tvec.x = tvec.x * rt_thrust
end

if tvec.y > 0 then
tvec.y = tvec.y * up_thrust
else
tvec.y = tvec.y * dn_thrust
end

if tvec.z > 0 then
tvec.z = tvec.z * fd_thrust
else
tvec.z = tvec.z * rv_thrust
end

tvec = player.Orientation:unrotateVector(tvec) --convert local vector to world space

--first compute some important data
wvel_len = wvel:getMagnitude()
local wvel_sqrd = wvel_len * wvel_len
local wvel_norm = normalize(wvel)
local wvel_norm_rot = player.Orientation:rotateVector(wvel_norm) --normalized velocity in model space
local wvel_norm_rot_no_z = wvel_norm_rot
wvel_norm_rot_no_z.z = 0
wvel_norm_rot_no_z = normalize(wvel_norm_rot_no_z)
angle_of_attack = -math.asin(wvel_norm_rot.y)
skid_angle = math.asin(wvel_norm_rot.x)

--lets do drag, figure out how much area is hitting the wind
--scale cross sections by components of the normalized, rotated velocity vector
local area = xy_area * math.abs(wvel_norm_rot.z) +
xz_area * math.abs(wvel_norm_rot.y) +
yz_area * math.abs(wvel_norm_rot.x)
--lets plug the drag equasion
local drag = drag_ce * area * 0.5 * atmo_pres * wvel_sqrd
dvec = (wvel_norm * -1) * drag

--now for lift
local lift = lift_ce * wing_area * 0.5 * atmo_pres * wvel_sqrd
local aoa_mat = ba.createOrientation(angle_of_attack,0,0)
lift_ref_vec = ( player.Orientation*aoa_mat):unrotateVector(ba.createVector(0,1,0))
lvec = lift_ref_vec * lift

--gravity is really easy
gvec = ba.createVector(0,-grav_force ,0) * shp_mass

--add em up to get our total force vector
fvec = tvec + dvec + lvec + gvec

--factor in mass
local massfactor = 1 / shp_mass
fvec2 = fvec * massfactor

--add to velocity
wvel = wvel + fvec2

--adjust for frametime
local wvel_timescaled = wvel * ba.getFrametime()

--use it
player.Position = player.Position + wvel_timescaled
player.Physics.Velocity = wvel --id rather not do this you know
end

]
$Hud:
[

if player:isValid() then
gr.setColor(255,0,0,255)
gr.drawString("Thrust:    "..math.ceil(tvec.x).." ' "..math.ceil(tvec.y).." ' "..math.ceil(tvec.z))
gr.setColor(0,255,0,255)
gr.drawString("Drag:      "..math.ceil(dvec.x).." ' "..math.ceil(dvec.y).." ' "..math.ceil(dvec.z))
gr.setColor(0,0,255,255)
gr.drawString("Lift:      "..math.ceil(lvec.x).." ' "..math.ceil(lvec.y).." ' "..math.ceil(lvec.z))
gr.setColor(255,255,0,255)
gr.drawString("Weight:    "..math.ceil(gvec.x).." ' "..math.ceil(gvec.y).." ' "..math.ceil(gvec.z))
gr.setColor(0,255,255,255)
gr.drawString("Total:     "..math.ceil(fvec.x).." ' "..math.ceil(fvec.y).." ' "..math.ceil(fvec.z))
gr.drawCircle(5, io.getMouseX()*wf, io.getMouseY()*hf)
gr.setColor(128,128,128,255)
gr.drawString("Altitude:  "..math.ceil(player.Position.y))
gr.drawString("Airspeed:  "..math.ceil(wvel_len))
gr.drawString("Vert Spd:  "..math.ceil(wvel.z))
gr.drawString("AoA:       "..math.deg(angle_of_attack))
gr.drawString("Skid:      "..math.deg(skid_angle))

local X,Y = player.Position:getScreenCoords()
if X then
X,Y=X*wf,Y*hf
local XX,YY = (player.Position + (tvec*0.0003)):getScreenCoords()
gr.setColor(255,0,0,255)
if XX then gr.drawLine(X,Y,XX*wf,YY*hf) end
XX,YY = (player.Position + (dvec*0.0003)):getScreenCoords()
gr.setColor(0,255,0,255)
if XX then gr.drawLine(X,Y,XX*wf,YY*hf) end
XX,YY = (player.Position + (lvec*0.0003)):getScreenCoords()
gr.setColor(0,0,255,255)
if XX then gr.drawLine(X,Y,XX*wf,YY*hf) end
XX,YY = (player.Position + (gvec*0.0003)):getScreenCoords()
gr.setColor(255,255,0,255)
if XX then gr.drawLine(X,Y,XX*wf,YY*hf) end
XX,YY = (player.Position + (fvec*10)):getScreenCoords()
gr.setColor(0,255,255,255)
if XX then gr.drawLine(X,Y,XX*wf,YY*hf) end
end
X,Y = (player.Position + wvel):getScreenCoords()
if X then prograderet( X, Y, math.ceil(wvel_len)) end
end

]
#End
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline WMCoolmon

  • Purveyor of space crack
  • 213
that ****ed up yaw axis that freespace uses gets really annoying here. i tried to remove it with scripting, but that didnt work. i know the wing commander people want that gone. not only does it interfere with flight as it is, but when i go to implement newtonian rotations and control surfaces, i will not be able to get axis data independant of eachother. when i check rotational velocity desired, any desired yaw from the yaw axis will also copy itself to the bank axis.

I've added a "Banking constant" field that should allow you to scale the amount of banking a ship does. The default is "0.5", and setting it to 0 should turn it off. I've tested it and it does seem to work. :p

"$Banking Constant:" is right after "$Rotdamp:" in ships.tbl

You can also change it dynamically with the BankingConstant variable in the scripting "physics" handle.

http://fs2source.warpcore.org/exes/latest/C12272007d.zip

I consider this a preliminary implementation. I could turn these into vectors for all three rotational axis to make it less specialized, if there's a reason to. All the code is doing is this:
Code: [Select]
#ifdef BANK_WHEN_TURN
// To change direction of bank, negate the whole expression.
// To increase magnitude of banking, decrease denominator.
// Adam: The following statement is all the math for banking while turning.
delta_bank = - (ci->heading * pi->max_rotvel.xyz.y) * pi->delta_bank_const;
#else
delta_bank = 0.0f;
#endif

pi->desired_rotvel.xyz.z = ci->bank * pi->max_rotvel.xyz.z + delta_bank;

BANK_WHEN_TURN is always defined so it's really only calculating this:
Code: [Select]
delta_bank = - (ci->heading * pi->max_rotvel.xyz.y) * pi->delta_bank_const;
pi->desired_rotvel.xyz.z = ci->bank * pi->max_rotvel.xyz.z + delta_bank;
where pi->delta_bank_const has been, up to this point, 0.5.
-C

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
ah cool, very useful.

i added some preliminary barometrics as well as max and min angle of attack settings.

i probably spent maybe 6 hours reading up on the barometric formula. not only is there a very complex formula to calculate are density at altitude, but theres also a table for changes in factors for different layers of the atmosphere. i only implemented the sea level row. but i think there are those who could use atmospheric layers. particularly a certain bsg episode depicts flying in a layered atmosphere. so you could use layers not only to simulate earthlike atmosphere, but also have a layer of doom that you cant escape from (due to skyrocketing atmospheric density and the velocity raping drag that ensues). this can be left open for further development.

the aoa limiter essentially scales back your lift coefficient when your angle of attack gets too high or too low. according to airfoil simulation, lift coefficient does change during flight and part of it is due to aoa. however realistically the lift coefficient is more on a gradient than a flat line between max and min. so tomorrow il consider adding that gradient. lift coefficient needs to clime as it reaches the max stall angle and drop as it reaches the minimum with the neutral angle, where the calculated coefficient best matches the one set in the physics parameters, lies directly in between. si if your max aoa is 20 degrees, your minimum is -10, and your aoa is 5, then the lift_ce var will equal the aoa compensated lift coefficient.  for negative angle of attack the lift coefficient may actually goes negative and will reach a negative stall at some point, where your lift_ce begins to return to zero.

another thing i will implement in the future is wing induced drag. this will require a wing chord and/or span variables. since wing area is already specified, i could just add one and calculate the other. and once all those features are in, il start working on newtonian torque. lack of torque effects is what causes that excessive horizontal lift component it seems. realistically an aircraft rudder cant produce enough torque to overcome the air pressures along the fusalage that want to keep it pointing into the wind. so pilots have to roll before theres enough force from the horizontal lift component to help the turn along. besides your passengers would hate you if you skid turned excessively :D.

*edit*
silly me, forgot to post the update

Code: [Select]
#Global Hooks
$GameInit:
[
--[[=============================]]--
--[[======= function defs =======]]--
--[[=============================]]--

setscreenvars = function() --scalers and constants for multi res support
local w = gr.getScreenWidth()
local h = gr.getScreenHeight()
local cx = w/2
local cy = h/2
local wf = 0
local hf = 0
local awh = 0
local hires = false

if w >= 1024 then
wf = w / 1024
hf = h / 768
awh = (wf + hf) / 2
hires = true
else
wf = w / 640
hf = h / 480
awh = ((wf + hf) / 2) * 0.625
hires = false
end

return w,h,cx,cy,wf,hf,awh,hires
end

normalize = function(v)
vlen = v:getMagnitude()
if vlen > 0 then vlen = 1 / vlen else vlen = 1 end
return v * vlen
end

mousejoy = function() --mousejoy function, returns a value from -1 to 1 depending on the mouse's position
local X = io.getMouseX()
local Y = io.getMouseY()

if hires then
X = (X / 511.5) - 1
Y = (Y / 383.5) - 1
else
X = (X / 319.5) - 1
Y = (Y / 239.5) - 1
end

return X,Y
end

prograderet = function(x,y,vel)
x, y = x*wf, y*hf --round theese, our vector gets jumpy

gr.setColor(72,192,72,222)

gr.drawGradientLine(x + (12*awh), y + (12*awh), x + (6*awh), y + (6*awh) )
gr.drawGradientLine(x - (12*awh), y - (12*awh), x - (6*awh), y - (6*awh) )
gr.drawGradientLine(x - (12*awh), y + (12*awh), x - (6*awh), y + (6*awh) )
gr.drawGradientLine(x + (12*awh), y - (12*awh), x + (6*awh), y - (6*awh) )

vel = tostring(vel)

gr.setColor(128,192,128,222)
gr.drawString(vel, x - (gr.getStringWidth(vel) / 2), y - (2*awh) )
end

w,h,cx,cy,wf,hf,awh,hires = setscreenvars()

--[[=============================]]--
--[[======= physics specs =======]]--
--[[=============================]]--


--[[==================]]--
--[[environmental vars]]--
--[[==================]]--

--alot more stuff here, alot of it i dont get, but was required for the barometric formula. many
--of these values are based on the international standard atmosphere, which are used to calibrate
--altimeters and other gauges in aircraft, aparently theres a table for different atmospheric
--layers, each with their own set of variables. so i might eventually allow a user to specify
--as many layers as they want. for example a mission in a gas giant might want a layer that
--you cant get out of (i think this happened in bsg, hint hint).

ter_base_lvl = -2000 --height of terrain model placement in fred, m
grav_accel = 9.78033 --acceleration of gravity, m/s^2
std_atmo_density = 1.293 --standard pressure at sea level, kg/m^3
std_temp = 288.15 --standard tempurature at sea level, kelvin
std_temp_lapse = 0.0065 --rate of tempurature loss starting at sea level and going up, kelvins/meter
atmo_mass = 0.0289644       --mass of atmosphere, kg/molar
gas_const = 8.31432 --universal gas constant, N·m / (mol·K), whatever the **** that means

--eventually i will support spherical gravity and atmosphere for some small scale launch,
--re-entry, and orbital manuvers. maybe il even support multiple spheres in a mission.
--the model is fully newtonian once lift and drag get zeroed out.

--ive added vars for more ships you can play around with, just remove the comment tags --[[ ]]-- from
--the ship specs you want to use all area values are actual ship cross sectional area, wing area is
--the area of any lifting surfaces, such as wings (in case of serapis and perseus), or lifting bodys
--(ulysses, pegasus). alternatively you can use a large up_thrust value to get helicopter style
--flight (erinyes). mass is ship volume * 100kg (assuming 100kg per cubic meter volume).
--thrust and coefficient values are ones which i find work well with the ship, however they are not
--perfect. there is a probability that one of the forces will overpower the others and youl get thrown
--out of the mission area. barometrics has reduced instances of getting tossed, however it can still
--happen. i attempted to use an airfoil simulation program on cross sections from actual fs models, in
--order to compute coefficients, usually with limited success (usually the program choked on my dxfs).

--[[================================================]]--
--[[instructions for computing area values in 3dsmax]]--
--[[================================================]]--
--to determine cross-section areas for drag area computation, export the ship to max and
--maintain scale! you may want to run mesh smooth on your models firsty, 3 iterations with
--smooth group seams enabled tends to work well. choose an orthagonal view for the plane you
--wish to work on first.  remember that conversion might switch axis order, so tetermine cross
--sections on the freespace coordanate system (x, y, z = side, up, front). top is xz, front is xy,
--and side is yz. flatten the ship to a plane using scale. if youre working on the xz plane you want
--to flatten by setting y to 0%. in other words scale the axis not in plane. then use the poly select
--tool (with ignore backfacing enabled) and select all visible polies and hit del. this leaves a
--flat cross section on the other side that you can measure. measuring both sides or not flattening
--would create more drag than your ship should actually create. open the utilities panel and select
--measure. grab the number from the surface area field. hit undo a few times to restore your
--model. repeat for the other 2 planes.

--for wing area, use the bottom view, select only lifting surfaces, such as wings. be sure to keep
--ignore backfacing on. you may need to use ctrl to select multiple sections. once thats done
--select 'invert selection' from the edit menu and hit delete. flatten the model as above.
--then go to measure and get the surface area value.

--you may also want to note the volume from the measure pane. you can then multiply it by a standard
--density value (i used 100 kg per cubic meter of ship). this lets massive ships actually feel massive
--remember that under newtonian, massive ships require more thrust.

--[[=================]]--
--[[ship physics vars]]--
--[[=================]]--

--[[
--ulysses, jumpy little bastard and not the best aircraft either
fd_thrust, rv_thrust, up_thrust, dn_thrust, lf_thrust, rt_thrust = 24000, 6000, 8000, 4000, 4000, 4000 --in newtons
shp_mass = 12169 --mas in kg, im using model volume of 121.69 * 100kg (assuming 100 kg per cubic meter of volume)
xy_area = 24.59 --area of frontal cross section for drag computation, square meters
xz_area = 104.26 --area of top down cross section for drag computation, m^2
yz_area = 53.72 --area of side cross section for drag computation, m^2
drag_ce = 0.0073 --drag coefficient, lower number = less drag, reccomend value between 0 and 2
lift_ce = 0.6 --lift coefficient, higher number = more lift, reccomend value between 0 and 0.1
wing_area = 52.59 --area of wings from top down perspective, square meters, recomend value less than xz_area
aoa_max = 15 --maximum angle of attack, angle relative to velocity that wings stop producing lift, degrees
aoa_min = -5 --minimum angle of attack, degrees
]]--

--[[
--serapis, handles better in the upper atmosphere
fd_thrust, rv_thrust, up_thrust, dn_thrust, lf_thrust, rt_thrust = 95000, 1000, 2000, 1000, 1000, 1000
shp_mass = 25327
xy_area = 44.59
xz_area = 170.8
yz_area = 76.93
drag_ce = 0.0123
lift_ce = 0.055
wing_area = 49.68
aoa_max = 20
aoa_min = -10
]]--

--
--perseus, sleek and fast and lots of lift
fd_thrust, rv_thrust, up_thrust, dn_thrust, lf_thrust, rt_thrust = 110000, 2000 ,1000, 1000, 1000, 1000
shp_mass = 10449
xy_area = 25.01
xz_area = 66.49
yz_area = 74.35
drag_ce = 0.04
lift_ce = 0.132
wing_area = 9.89
aoa_max = 30
aoa_min = -15
--

--[[
--pegasus, a good example of a stall happy physics profile
fd_thrust, rv_thrust, up_thrust, dn_thrust, lf_thrust, rt_thrust = 100000, 0, 0, 0, 0, 0
shp_mass = 37565
xy_area = 27.3
xz_area = 155.78
yz_area = 62.69
drag_ce = 0.035
lift_ce = 0.1
wing_area = 120
aoa_max = 20
aoa_min = -5
]]--

--[[
--erinyes, essentially no wings, so i gave it alot of vertical thrust
fd_thrust, rv_thrust, up_thrust, dn_thrust, lf_thrust, rt_thrust = 150000, 10000, 265000, 10000, 10000, 10000
shp_mass = 26954 --269.54
xy_area = 41.43
xz_area = 132.77
yz_area = 188.48
drag_ce = 0.03
lift_ce = 0.001
wing_area = 80.78 --its pods look somewhat lift capable, but lifting bodys tend to have sucky coefficients
aoa_max = 10
aoa_min = 0
]]--

wvel = ba.createVector(0,0,0)
init = false

]
$simulation:
[

player = mn.Ships["Alpha 1"]

if init == false then
if player:isValid() then player.Position = ba.createVector(0,0,0) end
wvel = ba.createVector(0,0,100)
init = true
end

--first lets do thrust, its longer due to tweaked input code
if player:isValid() then
tvec = ba.createVector(0,0,0)
--tvec.x = player.Physics.SideThrust
--tvec.y = player.Physics.VerticalThrust
tvec.x, tvec.y = mousejoy() --more usefull cause you can set lift to an arbitrary amount
tvec.y = -tvec.y
tvec.z = player.Physics.ForwardThrust

if tvec.x > 0 then
tvec.x = tvec.x * lf_thrust
else
tvec.x = tvec.x * rt_thrust
end

if tvec.y > 0 then
tvec.y = tvec.y * up_thrust
else
tvec.y = tvec.y * dn_thrust
end

if tvec.z > 0 then
tvec.z = tvec.z * fd_thrust
else
tvec.z = tvec.z * rv_thrust
end

tvec = player.Orientation:unrotateVector(tvec) --convert local vector to world space

--first compute some important data
wvel_len = wvel:getMagnitude()
local wvel_sqrd = wvel_len * wvel_len
local wvel_norm = normalize(wvel)
local wvel_norm_rot = player.Orientation:rotateVector(wvel_norm) --normalized velocity in model space
local wvel_norm_rot_no_x = wvel_norm_rot
skid_angle = math.asin(wvel_norm_rot.x)
wvel_norm_rot_no_x.x = 0
wvel_norm_rot_no_x = normalize(wvel_norm_rot_no_x)
angle_of_attack = -math.asin(wvel_norm_rot.y)
aoa_deg = math.deg(angle_of_attack)
--baromatric formula, maybe
atmo_density = std_atmo_density * (std_temp/(std_temp+std_temp_lapse*((player.Position.y-ter_base_lvl)-0))) ^ ((grav_accel*atmo_mass)/(gas_const*std_temp_lapse))


--lets do drag, figure out how much area is hitting the wind
--scale cross sections by components of the normalized, rotated velocity vector
local area = xy_area * math.abs(wvel_norm_rot.z) +
xz_area * math.abs(wvel_norm_rot.y) +
yz_area * math.abs(wvel_norm_rot.x)
--lets plug the drag equasion
local drag = drag_ce * area * 0.5 * atmo_density * wvel_sqrd
dvec = (wvel_norm * -1) * drag

--now for lift
local lift_ce_adj

if aoa_deg <= aoa_max and aoa_deg >= aoa_min then
lift_ce_adj = lift_ce
elseif aoa_deg > aoa_max then
local excess_aoa = aoa_deg - aoa_max
lift_ce_adj = lift_ce / excess_aoa
elseif aoa_deg < aoa_min then
local excess_aoa = aoa_min - aoa_deg
lift_ce_adj = lift_ce / excess_aoa
else
lift_ce_adj = lift_ce
end

local lift = lift_ce_adj * wing_area * 0.5 * atmo_density * wvel_sqrd
local aoa_mat = ba.createOrientation(angle_of_attack,0,0)
lift_ref_vec = ( player.Orientation*aoa_mat):unrotateVector(ba.createVector(0,1,0))
lvec = lift_ref_vec * lift

--gravity is really easy
gvec = ba.createVector(0,-grav_accel ,0) * shp_mass

--add em up to get our total force vector
fvec = tvec + dvec + lvec + gvec

--factor in mass
local massfactor = 1 / shp_mass
fvec2 = fvec * massfactor

--add to velocity
wvel = wvel + fvec2

--adjust for frametime
local wvel_timescaled = wvel * ba.getFrametime()

--use it
player.Position = player.Position + wvel_timescaled
player.Physics.Velocity = wvel --id rather not do this you know
else
init = false
end

]
$Hud:
[

if player:isValid() then
gr.setColor(255,0,0,255)
gr.drawString("Thrust:    "..math.ceil(tvec.x).." ' "..math.ceil(tvec.y).." ' "..math.ceil(tvec.z))
gr.setColor(0,255,0,255)
gr.drawString("Drag:      "..math.ceil(dvec.x).." ' "..math.ceil(dvec.y).." ' "..math.ceil(dvec.z))
gr.setColor(0,0,255,255)
gr.drawString("Lift:      "..math.ceil(lvec.x).." ' "..math.ceil(lvec.y).." ' "..math.ceil(lvec.z))
gr.setColor(255,255,0,255)
gr.drawString("Weight:    "..math.ceil(gvec.x).." ' "..math.ceil(gvec.y).." ' "..math.ceil(gvec.z))
gr.setColor(0,255,255,255)
gr.drawString("Total:     "..math.ceil(fvec.x).." ' "..math.ceil(fvec.y).." ' "..math.ceil(fvec.z))
gr.drawCircle(5, io.getMouseX()*wf, io.getMouseY()*hf)
gr.setColor(128,128,128,255)
gr.drawString("Altitude:  "..math.ceil(player.Position.y-ter_base_lvl))
gr.drawString("Airspeed:  "..math.ceil(wvel_len))
gr.drawString("Vert Spd:  "..math.ceil(wvel.y))
gr.drawString("AoA:       "..aoa_deg)
gr.drawString("Skid:      "..math.deg(skid_angle))
gr.drawString("Air Dnsty: "..atmo_density)

local X,Y = player.Position:getScreenCoords()
if X then
X,Y=X*wf,Y*hf
local XX,YY = (player.Position + (tvec*0.0003)):getScreenCoords()
gr.setColor(255,0,0,255)
if XX then gr.drawLine(X,Y,XX*wf,YY*hf) end
XX,YY = (player.Position + (dvec*0.0003)):getScreenCoords()
gr.setColor(0,255,0,255)
if XX then gr.drawLine(X,Y,XX*wf,YY*hf) end
XX,YY = (player.Position + (lvec*0.0003)):getScreenCoords()
gr.setColor(0,0,255,255)
if XX then gr.drawLine(X,Y,XX*wf,YY*hf) end
XX,YY = (player.Position + (gvec*0.0003)):getScreenCoords()
gr.setColor(255,255,0,255)
if XX then gr.drawLine(X,Y,XX*wf,YY*hf) end
XX,YY = (player.Position + (fvec*10)):getScreenCoords()
gr.setColor(0,255,255,255)
if XX then gr.drawLine(X,Y,XX*wf,YY*hf) end
end
X,Y = (player.Position + wvel):getScreenCoords()
if X then prograderet( X, Y, math.ceil(wvel_len)) end
end

]
#End
« Last Edit: December 17, 2007, 12:15:42 pm by Nuke »
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline Wanderer

  • Wiki Warrior
  • 211
  • Mostly harmless
I'm still going to say this one more time...

As long as you keep the system position vector based it is and won't ever be anything more than showcase or PoC. As it messes up far too many things elsewhere. For example landing (or crashing onto anything) is not even theoretically possible as the ship simply 'phases' or 'warps' through the surface. Same goes for 'midair' collisions or even weapons fire as the ships position is changed without moving the ship between these locations. Would it be based on velocities or something else that is used for moving the ship between the frames then it would be much better.
Do not meddle in the affairs of coders for they are soggy and hard to light

 

Offline WMCoolmon

  • Purveyor of space crack
  • 213
What does it need to be non-Position based?
-C

  

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
i dont like running with broke colision detection any more than you do. id rather replace player.Velocity with wvel, and have freespace run its collision detection and other velocity related checks. somewhere in freespace actual velocity is calculated based on velocity max, velocity desired, as well as all the damp, and accel settings. right after that is about where i need to tell the engine that player.Velocity = wvel.  then that velocity may be applied to whatever the game needs to apply it to, mainly collision detection, but some other things too like calculating your lead indicator position, ect. also id like to use that additive weapon velocity feature backslash implemented. as it stands weapons are totally unusable because they are too slow to keep up with the ship. from $simulation or $on frame seems my velocity is getting overridden after i set it, a new velocity is being computed based of freespace physics, and the velocity i want to use gets tossed.

all my flight model does this far is convert a bunch of physics data into a velocity vector. it essentially reads joystick data directly from the side, vertical and forward thrust values. checks a thrust table for how many newtons to produce, multiplies those values by toe -1 to 1 axis values and creates a force vector.

atmospheric density is computed based on y position and some atmospheric variables. angle of attack is computed based on angle relative to velocity (im assuming the air is relative to the mission grid, no wind).

that data i used to calculate force vectors for lift and drag seporately (though lift induced drag will be computed at some point and the calculations will need to cross reference eachother). some where in there a gravity force is computed based on gravitational accel * mass. the forces are added up and converted to an acceleration (force/mass).

that acceleration is then added to a vector called wvel. at this point wvel is represented in the same format freespace uses for .velocity, only it uses the old value so it conserves momentum. at this point i multiply the velocity by frame time to get the position i need to be at. id rather not do it but its the only way to test the flight model at the moment. id rather just apply the acceleration to player.velocity and if freespace's physics dont overwrite it it could be used without breaking anything.

what i need to fix it is a switch of sorts to disable freepace's physics calculation. a physics hook would be a good start. right after a new velocity is computed but before its applied to actual velocity. an override would completely kill freespace's physics calculation. that only need be done for a replacement physics model like this. alternatively you could introduce a switch concept. rather than putting a new hook everytime you want to get something to work. perhaps add a section to the scripting table for swtches. i could say perhaps $enable_freespace_physics: NO, similar to an override but independent of a corresponding hook. conditional overrides would be better, i could check if a particular mission has a physics profile, then if it does, switch off physics and use my system. otherwise lef freespace deal with it.

one thing i dont like about the new hook format is that you cant pass vars from say the $on frame hook to the $hud hook. i like outputting debug data to hud, which as far as i know can only be done through the $hud hook. also you cant access functions or vars from $on game init, so you got to put those in global hooks' $gameinit. also it seems yore not allowed to change variables defined in global hooks, you can however read them. it makes no since to have to recompute redundant data that was computed in another hook. though the namespace independence is something that can be useful. be nice if there were readGlobal("var") and writeGlobal("var", data) functions too allow passage of custom data from hook to hook, without killing the namespace feature.
« Last Edit: December 18, 2007, 12:03:05 am by Nuke »
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline Wanderer

  • Wiki Warrior
  • 211
  • Mostly harmless
Hmm.. true.. But you could probably check the effect of the changes by standard trial and error method and get the needed 'tweak values' (multipliers) to get it work with your physics approach. For example 'corridor mode' uses velocity based 'movement barriers'. Sure it would have been simpler just to stick with position data but i wanted to preserve as much of the collision detection as possible.
Do not meddle in the affairs of coders for they are soggy and hard to light

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
its easier to put barriers in than to take them out. to build a proper flight model you need to start with newtonian physics and build up from there. but freespace likes to cap and damp your velocity. its a hard limitation to work around. il work on a solution once the physics model is fairly complete. if i get this thing to work completely it opens the door to some cool possibilities like ww2 air combat and olot of other things. a helicopter sim could be done on this model. uncomment the physics vars for the erinyes and give it a spin, i set that one up as a vtol demo. make some helicopter models and call it a mod :D
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline Herra Tohtori

  • The Academic
  • 211
  • Bad command or file name
Looks very interesting.

But... I'm wondering.

How is the glide done in BtRL? Scripting or in-engine code?

If it's in-engine code, isn't that a way to disable FS2_physics calculations (or, well, part of them anyway) right there? The problem seems to be that FS2 tries to make it's own non-newtonian calculations on the background and you're trying to override them in the script with changing the position vector manually. But isn't the glide system already a possibility to enable effectively newtonian physics? Without the speed limit the BtRL currently has, that is. It has the ability to change ship's vector in the glide mode with thrusters, up to the velocity limit.

If it's done by scripting as well... well, perhaps adding atmo flight to that script would be a good place to start?

You will need to add control surfaces to enforce stability in that case, though, so that yawing doesn't make your ship fly sideways, since the FS2 physics won't be helping with keeping the ship flying towards where it's pointed at any more. Or have you done something else already to avoid ships flying sideways? I'm not so good at reading the scripts but I didn't notice anything like that.

The thing is, to add stabilizers realistically you would need to already put control surfaces onto them, and that would force you to include a way to change their lift coefficients with input controls, and a way for them to change the ship's attitude. Also, you need to take into account that the ship can have sideways AOA as well as pitch-oriented, and it affects the hull and control surfaces... essentially it affects drag also, because flying sideways increases the cross-section of the ship in the airflow, causes turbulence and other nasties like that... And even though I don't really know theg scripting system I can see it's not going to be a very coder-friendly process... :shaking:


Other thing I was wondering. Why don't you calculate the lift, drag and propulsion force vectors in relation to ship, bunch them all together and then convert that net force vector to velocity change vector (ie. acceleration) and only after you have the net force vector calculated, convert it to global reference frame co-ordinate system. That way you'd only need to do that conversion once. Gravity is done in general reference frame anyway so it doesn't need to be converted at any phase according to my understanding.

Of course, if the engine can get acceleration values from LUA directly, that would be the easiest way of doing this. Is that possible? It would make all the conversions from acceleration to velocity change (not to mention position change) redundant, the only thing you'd need to worry is changing the ship-related acceleration to global reference frame.


As to the physics of the equations, I don't see anything fundamentally wrong with them so far... apart from them being rough approximations of aerodynamics, that is. But in a game like this, calculating the airflow based on the model mesh is not really necessary, tabled aerodynamic values will do very well (MS Flight Simulator uses them as well, so you're in good company). If we want accurate aerodynamics we need to port the FS2 media to X-Plane. ;7 But for example, drag coefficient changes somewhat when you enter sub-sonic, supersonic and hypersonic areas of velocity, what with compressed shockwaves going on around the ship bouncing to and from the surface, and changing the viscous properties of the air a bit. But I daresay that's a bit more advanced physics modelling and should perhaps wait until you get the fundamental stuff working properly with the rest of the game.


I might add that I know next to nothing about the scripting system and what it allows so I'm just kinda spewing ideas around. They might not be possible at all, but then again, they might have some value. :rolleyes:
There are three things that last forever: Abort, Retry, Fail - and the greatest of these is Fail.

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
Looks very interesting.

thanks :D

Quote
You will need to add control surfaces to enforce stability in that case, though, so that yawing doesn't make your ship fly sideways, since the FS2 physics won't be helping with keeping the ship flying towards where it's pointed at any more. Or have you done something else already to avoid ships flying sideways? I'm not so good at reading the scripts but I didn't notice anything like that.

The thing is, to add stabilizers realistically you would need to already put control surfaces onto them, and that would force you to include a way to change their lift coefficients with input controls, and a way for them to change the ship's attitude. Also, you need to take into account that the ship can have sideways AOA as well as pitch-oriented, and it affects the hull and control surfaces... essentially it affects drag also, because flying sideways increases the cross-section of the ship in the airflow, causes turbulence and other nasties like that... And even though I don't really know theg scripting system I can see it's not going to be a very coder-friendly process... :shaking:

alot of the quirks are due to a lack of rotational physics in my model. the intense slide you get when banking is due to the fact that there is no force resisting the turn. in a real aircraft, the rudder is really incapable of turning you due to the pressure forces around the fuselage. in a medium sized airfraft you could jam full rudder and only get a degree or two of yaw out of the plane a second. let go of the rudder and you instantly snap back to straight ahead as far as lateral angle of attack does. the aircraft wants its nose to the wind. its actually rather difficult to get a large lateral aoa in an aircraft.

pitch is a much more responsive because of the massive forces the lifting surfaces produce. i learned of a force known as the pitching moment which makes the front wing want to pitch down in response to airflow. so the horizontal stabalizers tend to produce a down force to compensate.   theres also the added leverage and the fact that the horizontal stabilizer has more control surface area than the rudder, main reason is pitch control is so much more important than rudder. the rudder is only useful in a coordinated turn, which is used mostly when you need to turn by a wide angle in a small amount of space. most of the force that contributes to the turn is from that force you see when you bank in my model. they call it your horizontal lift component. you use a combination of pitch and yaw to get the nose of the aircraft along the vector of the horizontal lift component. this allows faster turning than either yaw or pitch by itself.

so those are some of the things i must simulate. i could probibly calculate the yaw resistance based on the lateral aoa value and the yz cross section area. pitch resistance can be computed from the xz plane and roll resistance off of the wing and rudder area. rather than simulate control surfaces directly, il generate a rotational torque with force proportional to a percentage of the lift force produced by the wing. for yaw the force will be based on rudder lift (il probibly compute it in the same way i compute wing lift). a neutral airfoil always has a lift coefficient of 0 and 0 angle of attack. pitch force can be computed the same way. so i need to compute 6 and more forces in total, and turn the ship accordingly. so the torque model will be even more complicated to say the least. il probably start with basic conservation of angular momentum and newton force from rcs thrusters, then add in atmospheric interaction.

Quote
Other thing I was wondering. Why don't you calculate the lift, drag and propulsion force vectors in relation to ship, bunch them all together and then convert that net force vector to velocity change vector (ie. acceleration) and only after you have the net force vector calculated, convert it to global reference frame co-ordinate system. That way you'd only need to do that conversion once. Gravity is done in general reference frame anyway so it doesn't need to be converted at any phase according to my understanding.

thats actually how i did it, if you go to external view there are lines which draw the force vectors. im using force vectors and not acceleration vectors because most of the equations give force values, thrusts are direct force values. gravity is the exception. i have to multiply it by mass to get a force. they are summed up as forces, to a combined force vector, which is devided by mass to become an acceleration vector which may be applied to velocity.

Quote
As to the physics of the equations, I don't see anything fundamentally wrong with them so far... apart from them being rough approximations of aerodynamics, that is. But in a game like this, calculating the airflow based on the model mesh is not really necessary, tabled aerodynamic values will do very well (MS Flight Simulator uses them as well, so you're in good company). If we want accurate aerodynamics we need to port the FS2 media to X-Plane. ;7 But for example, drag coefficient changes somewhat when you enter sub-sonic, supersonic and hypersonic areas of velocity, what with compressed shockwaves going on around the ship bouncing to and from the surface, and changing the viscous properties of the air a bit. But I daresay that's a bit more advanced physics modelling and should perhaps wait until you get the fundamental stuff working properly with the rest of the game.

theres really no such thing as a simple aerodynamic model. there are alot of forces we know about and many we dont. also this is really the first time ive done anything with physics. i am not formally physics educated. so its gonna be crude. none the less ive impressed myself with how far its come, and i seem to have a natural aptitude for physics. i rather enjoy seeing what my ship is gonna do next. ive seen some rather comical flight characteristics thus far. things like considering geometry are out of the question. not with my skill level. im happy with crude cross sections and fantom airfoils :D
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline WMCoolmon

  • Purveyor of space crack
  • 213
The physics in the freespace engine bear little resemblance to reality. Basically, forces etc. are done away with in ship movement and instead there's a 'desired velocity' vector. The ship "accelerates" to the desired velocity from the current velocity based on a dampening value that keeps the ship from instantly changing velocity.

You can probably do things like rotation from a collision based on momentum, but it pretty much invalidates a lot of 'proper' physics.
-C

 

Offline Herra Tohtori

  • The Academic
  • 211
  • Bad command or file name
Yeah. Aerodynamics can be modelled in a complex or more complex way. In a relative perspective, the "merely complex" way could be described as "simple". :p

I am also quite sure that most of FS2 players would be content with the crudest of atmo models, if it can just be made playable and accurate enough to not be completely out of intuitional range of any human...


On the topic of lateral pitch... actually you can get almost as much lateral AOA out of afighter-sized airplane as pitch AOA, but it just doesn't change the aircraft's vector much at all, it just makes it fly slightly sideways. Actual degrees of AOA are almost same in both pitch and lateral regard, but their consequences are vastly different. Increasing pitch AOA increases the AOA of wings, which increases the lift a lot, while increasing the yaw AOA doesn't really make that much of a difference in the forces generated by the body sideways. In the pitch case, the wings start rapidly changing the vector of the airplane towards the direction of the changed pitch, while the body of the aircraft doesn't do that. That's why vertical stabilizer doesn't turn the airplane as fast as roll-pitch turn does.


If the airplane had symmetric aerofoils vertically installed at the same place as the main wings, changing the lateral AOA would have a lot more effect on the plane's vector...
There are three things that last forever: Abort, Retry, Fail - and the greatest of these is Fail.

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
The physics in the freespace engine bear little resemblance to reality. Basically, forces etc. are done away with in ship movement and instead there's a 'desired velocity' vector. The ship "accelerates" to the desired velocity from the current velocity based on a dampening value that keeps the ship from instantly changing velocity.

You can probably do things like rotation from a collision based on momentum, but it pretty much invalidates a lot of 'proper' physics.

that said how much you figure changing orientation every frame is going to hurt colision detection?
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline WMCoolmon

  • Purveyor of space crack
  • 213
A lot, probably.

Really what you're supposed to do with scripting stuff is set things up so that the engine can handle all of the interframe movement, while scripting comes in only when something changes. That's very difficult to do with Freespace 2, especially in cases like this, where the physics system is so damn specific.

The camera system is pretty much the best model of how things are supposed to be scripted that I can think of, but even that's a rather basic example.

I've been meaning to add in some kind of hardcoded frame-limit feature, so you could for instance have a hook run only every 4 frames or every eighth of a second or something. This would be good for HUD stuff, although there's the issue of making it so that not _everything_ falls on the same frame; possibly adding an additional field that lets you increment it so it's the 2/8th second, and then you could use other fields (eg update radar at 1/8, left hand gauges at 2/8, right hand gauges at 3/8, do some AI at 4/8, and so on)
-C

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
that could always be done by

Code: [Select]

if counter == nil then
  counter = 0
elseif counter == 4 then
  doStuff()
  counter = 0
else
  counter = counter + 1
end

which is about how i intend to to rtt stuff, probibly precomputing all the data to be drawn in the previous frame. id rather frame limiting not be forced since its really easy to set it up in lua. that would also throw off timing too. id rather it be something i can explicitly define. unless of course i could tell the feature how frequently to run. probibly add a +frame_skip: x field after the lua block. ba.getFrametime would need to be aware of the extra time that passed so as not to hurt timing.

still there might be script i want to run every frame say if i calculate the gauge data every 4 frames, is still want to have the draw functions run every frame, so as not to get an annoying flicker. perhaps multiple code blocks per hook, where each could have their on frameskip parameter.
« Last Edit: December 19, 2007, 07:01:13 am by Nuke »
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN