Announcement

Collapse
No announcement yet.

Relative Physics Problem

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • replied
    I have the code working and my airplane yaws, pitches and rotates but it does not move as in I cannot control it. I want to go foward then turn left then come into land can't do it because it is just acting like a helicopter up/down, yaw and pitch but it has no speed so I can't go forward or any other direction I can only face in different directions and it does move slightly on it own but without my control so it will just float away.

    Please help. Thanks.

    Leave a comment:


  • replied
    Syhon, I have to thank you. Your post helped me to make my spaceship move. After a couple of weeks I ended up with this: http://www.youtube.com/watch?v=FdkKXo5b09U.
    For more details have a look at my Work in Progress thread, it's linked to in my sig.

    Leave a comment:


  • replied
    Originally posted by KongWeezY View Post
    where is the AR_AircraftContent and AR_AircraftFactory code... can not get this to work...
    Your Factory and Content scripts should extend the ones I said, and the content is trivial, merely telling UDK what models you're going to be using. You would be best to write your own, but here's an example:
    Code:
    class AR_AircraftFactory extends UTVehicleFactory placeable;
    
    defaultproperties
    {
    	Begin Object Name=SVehicleMesh
    		SkeletalMesh=SkeletalMesh'AR_Content.AR_Biplane'
    		Translation=(X=-40.0,Y=0.0,Z=-70.0)
    	End Object
    
    
    	Begin Object Name=CollisionCylinder
    		CollisionHeight=+120.0
    		CollisionRadius=+200.0
    		Translation=(X=0.0,Y=0.0,Z=-40.0)
    	End Object
    
    	VehicleClassPath="AirRaid.AR_AircraftContent"
    	DrawScale=1
    }

    Leave a comment:


  • replied
    where is the AR_AircraftContent and AR_AircraftFactory code... can not get this to work...

    Leave a comment:


  • replied
    Finalised Code, somewhat.

    Using the below key bindings, my AR_Aircraft class has the following code:

    Code:
    class AR_Aircraft extends UTAirVehicle;
    
    /* etc */ 
    
    var float AR_MaxLift, AR_TurnSpeed, AR_Speed, AR_CurrentForward, AR_AddedLiftSpeed, AR_Acceleration;
    
    /* etc */
    
    simulated function AirRaidKinematics(float DeltaTime)
    {
    	local Vector AR_ForceApplication, AR_ForceRotation, AR_ForwardsNormal, AR_UpwardsNormal, AR_SidewardsNormal;
    	local Vector AR_ForceRotationVectX, AR_ForceRotationVectY, AR_ForceRotationVectZ;
    	local float AR_Lift, AR_ForwardSpeed, AR_NewRise;
    
    	// While there is a player in the biplane:
    	if (PlayerController(Controller) != None)
    	{
    		GetAxes(Rotation, AR_ForwardsNormal, AR_SidewardsNormal, AR_UpwardsNormal);
    		
    		// It's probably unnecessary to normalise these:
    		AR_ForceRotationVectX = Normal(AR_ForwardsNormal);
    		AR_ForceRotationVectY = Normal(AR_SidewardsNormal);
    		AR_ForceRotationVectZ = Normal(AR_UpwardsNormal);
    
    		// Rise is NOT between -1 and 1, like it said it was
    		AR_NewRise = 0;
    		if (Rise != 0) AR_NewRise = Rise / Abs(Rise); // Avoid divide by 0
    
    		// Calculate the XYZ components of the relative steering:
    		// Generic controls Steering, Throttle and Rise are set by the controller
    
    		// Roll
    		AR_ForceRotationVectX.X *= 35 * -AR_NewRise; // Steering is between -1 and 1	
    		AR_ForceRotationVectX.Y *= 35 * -AR_NewRise; // Steering is between -1 and 1	
    		AR_ForceRotationVectX.Z *= 35 * -AR_NewRise; // Steering is between -1 and 1	
    
    		// Pitch
    		AR_ForceRotationVectY.X *= 30 * Throttle; // Throttle is between -1 and 1
    		AR_ForceRotationVectY.Y *= 30 * Throttle; // Throttle is between -1 and 1
    		AR_ForceRotationVectY.Z *= 30 * Throttle; // Throttle is between -1 and 1
    
    		// Yaw
    		AR_ForceRotationVectZ.X *= 25 * -Steering; // AR_NewRise is between -1 and 1
    		AR_ForceRotationVectZ.Y *= 25 * -Steering; // AR_NewRise is between -1 and 1
    		AR_ForceRotationVectZ.Z *= 25 * -Steering; // AR_NewRise is between -1 and 1
    
    		// Add them together to get final global rotation vector:
    		AR_ForceRotation.X = AR_ForceRotationVectX.X + AR_ForceRotationVectY.X + AR_ForceRotationVectZ.X;
    		AR_ForceRotation.Y = AR_ForceRotationVectX.Y + AR_ForceRotationVectY.Y + AR_ForceRotationVectZ.Y;
    		AR_ForceRotation.Z = AR_ForceRotationVectX.Z + AR_ForceRotationVectY.Z + AR_ForceRotationVectZ.Z;
    
    		AR_CurrentForward += AR_Acceleration * Throttle;
    		AR_ForwardSpeed = AR_CurrentForward * 2.2;
    		// AR_ForwardSpeed is not necessarily true - I'd optimally need to use some 
    		// calculation based off Velocity and current forwards direction Vector...
    
    		// Calculate lift for the biplane:
    		AR_Lift = (AR_ForwardSpeed + AR_AddedLiftSpeed) * Abs(Cos(Rotation.Pitch));
    		if (AR_Lift > AR_MaxLift) AR_Lift = AR_MaxLift;
    		
    		// This gives lift upwards relative to its up-axis and push forwards relative to its forward-axis:
    		AR_ForceApplication.X = AR_UpwardsNormal.X * AR_Lift + AR_CurrentForward * AR_ForwardsNormal.X;
    		AR_ForceApplication.Y = AR_UpwardsNormal.Y * AR_Lift + AR_CurrentForward * AR_ForwardsNormal.Y;
    		AR_ForceApplication.Z = AR_UpwardsNormal.Z * AR_Lift + AR_CurrentForward * AR_ForwardsNormal.Z;
    		
    		// Add forces and rotations
    		Mesh.AddForce(AR_ForceApplication);
    		Mesh.AddTorque(AR_ForceRotation);
    	}
    	else
    	{
    		AR_CurrentForward = AR_Speed; // Biplane propellor thrust sets to default
    	}
    }
    
    
    simulated function Tick(float DeltaTime)
    {
    	AirRaidKinematics(DeltaTime);
    	Super.Tick(DeltaTime);
    }
    
    /* etc */
    Note, to implement the aircraft 'properly' as UDK does, I have three classes: AR_Aircraft (extends UTAirVehicle), AR_AircraftContent (extends AR_Aircraft), and AR_AircraftFactory (extends UTVehicleFactory). For more information, look at the Cicada. The code for the AR_Aircraft class above should help anyone implement (very) rough aircraft physics.

    As mentioned, I changed the key bindings for my specific game inside UTInput.ini:
    Code:
    Bindings=(Name="SpaceBar",Command="GBA_Jump")
    Bindings=(Name="W",Command="GBA_MoveForward")
    Bindings=(Name="S",Command="GBA_Backward")
    Bindings=(Name="A",Command="GBA_StrafeLeft")
    Bindings=(Name="Q",Command="GBA_Duck")
    Bindings=(Name="E",Command="GBA_Jump")
    Bindings=(Name="D",Command="GBA_StrafeRight")
    Bindings=(Name="LeftControl",Command="GBA_Use")
    Q, E to roll.
    A, D to yaw.
    W, S to pitch (also gains speed).
    LeftControl to hop in or out (replaces E).
    (Without changing bindings, the normal controls would be C, Spacebar to roll)

    By all means, take the code, extend it, and reply to me with what you've done with it.

    Thanks; enjoy.

    Leave a comment:


  • replied
    Current Solution

    As I said, "AddTorque" does apply globally, so my workaround has been to manually calculate the relative torque-add components, then apply them in that global sense. I used the normals from the "GetAxes" method that Seenooh gave me.

    Apropos, Vector "Y" is now renamed "AR_SidewardsNormal":

    Code:
    GetAxes(Rotation, AR_ForwardsNormal, AR_SidewardsNormal, AR_UpwardsNormal);
    
    // It's probably unnecessary to normalise these:
    AR_ForceRotationVectX = Normal(AR_ForwardsNormal);
    AR_ForceRotationVectY = Normal(AR_SidewardsNormal);
    AR_ForceRotationVectZ = Normal(AR_UpwardsNormal);
    
    // Calculate the XYZ components of the relative steering:
    AR_ForceRotationVectX.X *= 35 * Steering; // Steering is between -1 and 1	
    AR_ForceRotationVectX.Y *= 35 * Steering; // Steering is between -1 and 1	
    AR_ForceRotationVectX.Z *= 35 * Steering; // Steering is between -1 and 1	
    
    AR_ForceRotationVectY.X *= 30 * Throttle; // Throttle is between -1 and 1
    AR_ForceRotationVectY.Y *= 30 * Throttle; // Throttle is between -1 and 1
    AR_ForceRotationVectY.Z *= 30 * Throttle; // Throttle is between -1 and 1
    
    AR_ForceRotationVectZ.X *= 12 * Rise; // Rise is between -1 and 1
    AR_ForceRotationVectZ.Y *= 12 * Rise; // Rise is between -1 and 1
    AR_ForceRotationVectZ.Z *= 12 * Rise; // Rise is between -1 and 1
    
    // Add them together to get final global rotation vector:
    AR_ForceRotation.X = AR_ForceRotationVectX.X + AR_ForceRotationVectY.X + AR_ForceRotationVectZ.X;
    AR_ForceRotation.Y = AR_ForceRotationVectX.Y + AR_ForceRotationVectY.Y + AR_ForceRotationVectZ.Y;
    AR_ForceRotation.Z = AR_ForceRotationVectX.Z + AR_ForceRotationVectY.Z + AR_ForceRotationVectZ.Z;
    I probably could have used a better naming convention... Anyway, now there's mainly tweaking to do. I'll post back here with the final script (if I ever finalise it). I'll probably start other threads as I find separate issues.

    Thanks for all your help!

    PS: Strange, in basically all my studies, Y-axis is up and Z-axis faces outwards/forwards. I come less from a game-engine-user perspective and more from Mathematics, but maybe I'm wrong. I guess it doesn't matter either way, as long as I know which is which for UDK.

    Leave a comment:


  • replied
    in any system i've ever worked with (admittedly not many), up/down is Z ...

    Leave a comment:


  • replied
    Code:
    AR_Lift = AR_Forward * 1.5 * Abs(Cos(Y.Pitch));
    That piece of code doesn't compile, as Y is a Vector. Rotation.Pitch does work for that piece of code, but your contribution is still appreciated, thanks.

    (I have previously noted to myself that it would be more correct to check the current Pitch against the Pitch of the plane's Velocity-Vector; however, I'm happy with the responsiveness of the movement that this code simulates, for the purposes of the cartoon-ish game I am attempting to create.)


    I did have a fresh look at the rest of my code though, and determined this replacement:
    Code:
    // This gives lift upwards relative to its up-axis and push forwards relative to its forward-axis:
    AR_ForceApplication.X = AR_UpwardsNormal.X * AR_Lift + AR_ForwardsNormal.X * AR_Forward;
    AR_ForceApplication.Y = AR_UpwardsNormal.Y * AR_Lift + AR_ForwardsNormal.Y * AR_Forward;
    AR_ForceApplication.Z = AR_UpwardsNormal.Z * AR_Lift + AR_ForwardsNormal.Z * AR_Forward;
    That fixes the "always travels forward along the global x-axis" issue. Of course, I should have seen it before.

    (Incidentally, does anyone know why UDK decided to swap all the axes around, so that the x-axis in UDK is actually the z-axis for most normal 3D systems?)


    Regardless, the main issue is still how rotation is applied. Everything else works now, save for the issue demonstrated in my crude diagram above: if I spin the plane around in one axis, it no longer rotates correctly when rotating about another axis. It treats the current orientation of the plane as global orientation. I think it has to do with the following line but I am not sure exactly why it would be wrong, apart from the fact it just seems to apply the values globally:

    Code:
    // Rotate the biplane
    AddTorque(AR_ForceRotation);
    Thank you for all your help so far. I'm still looking at the code; I'll post back here if I solve it. Thanks.

    Leave a comment:


  • replied
    You welcome. =)

    Look here:

    Code:
    // Calculate lift for the biplane:
    AR_Lift = AR_Forward * 1.5 * Abs(Cos(Rotation.Pitch));
    Do you see in my previous post where I declared local Y ? Then GetAxes? Y becomes the Y axis relative to your object... So try this out:

    Code:
    AR_Lift = AR_Forward * 1.5 * Abs(Cos(Y.Pitch));
    I believe wherever you use Rotation in your calculations it'll give you that global issue. I hope this helps you out.

    Leave a comment:


  • replied
    Thanks Seenooh, and MonsOlympus, that fix was very helpful and has fixed the movement considerably.

    However, I still have the particular problem where the rotations are being applied globally. Let me try to illustrate:



    Similarly, if I rotate the biplane around so it is facing down the negative x-axis: it continues backwards, still going forward in the global x-axis.

    Leave a comment:


  • replied
    Originally posted by MonsOlympus View Post
    Id have to agree seenooh, when they posted earlier I double checked over this and the normalized vector rotation is the only major difference between this force application and that of the scorpions booster. That leads me to believe this is whats causing your local vs world coordinate system problem
    Yeah I think that's the issue.

    Anyways I editted my previous post because I think I found another problem...

    Leave a comment:


  • replied
    Id have to agree seenooh, when they posted earlier I double checked over this and the normalized vector rotation is the only major difference between this force application and that of the scorpions booster. That leads me to believe this is whats causing your local vs world coordinate system problem

    Leave a comment:


  • replied
    I'm not sure, but I think your problem is here:

    Code:
    AR_ForwardsNormal = Normal(Vector(Rotation));
    and here

    Code:
    // Calculate UpwardsNormal of the plane so I can lift it in that direction:
    AR_UpwardsNormal.X = - AR_ForwardsNormal.Z;
    AR_UpwardsNormal.Y =  AR_ForwardsNormal.Y;
    AR_UpwardsNormal.Z =  AR_ForwardsNormal.X;

    You are trying to get the forward vector that the plane is facing in a wrong way. Also AR_UpwardsNormal calculation is incorrect. This is basically the up vector relative to the plane. I think you should try this instead:

    Code:
    local vector Y; 
    
    GetAxes(Rotation,AR_ForwardsNormal,Y,AR_UpwardsNormal);
    Hope that helps.

    Leave a comment:


  • replied
    Apologies, the steering of the biplane is as follows:
    The biplane will roll (and yaw slightly) upon pressing 'A' and 'D' keys.
    The biplane will pitch up and down by pressing the 'W' and 'S' keys.

    This works, using the values from Steering and Throttle.
    Code:
    AR_ForceRotation.Z = 12 * Steering
    This line is deliberate (at least for now), imitating the slight yaw the biplane will have when it rolls. Sorry for the confusion, that was my fault.

    Every tick, the biplane is to be pushed forward based on its propulsion, and upwards based off its lift.
    Now, this all appears to be working somewhat; however, the problem is that the forces are apparently being applied from a global perspective.

    For example: its forward-push is always in the global x-axis, instead of being pushed forward in the direction of the plane's heading. The pitch and roll is also applied globally, so that when the biplane is facing another direction, the pitch will still rotate it in global angles, thus meaning it can't turn and then pitch down properly.

    I hope this makes sense. Sorry Seenooh, that just made the rotation super duper fast. I'm looking at these lines to be the culprit:

    Code:
    		// Propel the biplane
    		AddForce(AR_ForceApplication);
    
    		// Rotate the biplane
    		AddTorque(AR_ForceRotation);
    However, I'm not sure. Would it be more beneficial to include all my scripts in a link?

    Leave a comment:


  • replied
    rotators have a range of 65535 units

    Leave a comment:

Working...
X