Page 1 of 1

Character Inside A Helicopter

Posted: Tue Sep 04, 2012 6:34 pm
by Garold


I have a few questions :)

I have built the cargo bay of the helicopter using a compound body, is this the preferred solution?

Code: Select all

            //Build the helicopter cargo bay
            var bodies = new List<CompoundShapeEntry>() 
            {
                // floor
                new CompoundShapeEntry(new BoxShape(2.3f,0.2f,9.3f), new Vector3(0, 3, 0), 1),
                // ceiling
                new CompoundShapeEntry(new BoxShape(2.3f,0.2f,9.3f), new Vector3(0, 5, 0), 1),
                // back wall
                new CompoundShapeEntry(new BoxShape(2.3f,2f,0.2f),new Vector3(0,4.3f,-4.7f),1),
                // left wall
                new CompoundShapeEntry(new BoxShape(0.2f,2.4f,9.3f), new Vector3(1.25f, 4.1f, 0), 1),
                // right wall
                new CompoundShapeEntry(new BoxShape(0.2f,2.4f,9.3f), new Vector3(-1.25f, 4.1f, 0), 1)
            };

            Helicopter = new CompoundBody(bodies);
            Helicopter.Position = new Vector3(950, -6, -950);
            Space.Add(Helicopter);
I move the helicopter around in an identical fashion to the CharacterPlaygroundDemo, I have an EntityMover, and I've recently added an EntityRotator. The helicopter is working great, it goes where I want precisely. The problem I've noticed since adding the rotator is; the character does not rotate with the helicopter. I can think of a possible solution: when the character is in contact with the cargo bay floor and the helicopter is rotating add the rotation of the helicopter to the camera. What is the best way of determining if the character is in contact?

Additionally, If I throw a grenade from the back of the helicopter, its trajectory is incorrect, I presume I need to add the character's velocity to the grenade velocity?

Thanks for taking the time to look at this:)

Re: Character Inside A Helicopter

Posted: Tue Sep 04, 2012 6:59 pm
by Norbo
I have built the cargo bay of the helicopter using a compound body, is this the preferred solution?
If it does what you need it to do, then yup. Using a simplified representation like that is faster than a MobileMeshShape or something else complex.
What is the best way of determining if the character is in contact?
One option would be to check if the CharacterController.SupportFinder.Traction/SupportData.Value.SupportObject is the helicopterEntity.CollisionInformation object.

More generally, you can control the yaw of the character whenever it stands on an entity with angular velocity. The CharacterControllerInput has a commented section which does this:

Code: Select all

                //Rotate the camera of the character based on the support velocity, if a support with velocity exists.
                //This can be very disorienting in some cases; that's why it is off by default!
                if (CharacterController.SupportFinder.HasSupport)
                {
                    SupportData? data;
                    if (CharacterController.SupportFinder.HasTraction)
                        data = CharacterController.SupportFinder.TractionData;
                    else
                        data = CharacterController.SupportFinder.SupportData;
                    EntityCollidable support = data.Value.SupportObject as EntityCollidable;
                    if (support != null && !support.Entity.IsDynamic) //Having the view turned by dynamic entities is extremely confusing for the most part.
                    {
                        float dot = Vector3.Dot(support.Entity.AngularVelocity, CharacterController.Body.OrientationMatrix.Up);
                        Camera.Yaw += dot * dt;
                    }
                }
Additionally, If I throw a grenade from the back of the helicopter, its trajectory is incorrect, I presume I need to add the character's velocity to the grenade velocity?
Yup.

Re: Character Inside A Helicopter

Posted: Tue Sep 04, 2012 7:50 pm
by Garold


Thanks Norbo, you are a star!

I have left the compound body code alone, as you said if the hat fits..

The grenade problem was just that simple,worked first time.

Code: Select all

grenadePhysics.LinearVelocity = (SM.Camera.WorldMatrix.Forward * 20) + SM.Character.CharacterController.Body.LinearVelocity;
Likewise, all I did to fix the helicopter / character rotation was to uncomment the code in CharacterControllerInput, again it work first time!

Thanks again. BTW I have nominated you for the Nobel Physics Prize.

Re: Character Inside A Helicopter

Posted: Tue Sep 04, 2012 8:33 pm
by Norbo
BTW I have nominated you for the Nobel Physics Prize.
Thank you! With that recognition, maybe someone out there will take my QM interpretation, using many-dimensioned colorful blocks and balls as the physically superfundamental basis for apparent configuration amplitude flows, seriously. It's technically untestable, but the math is so elegant and the ball-block structures are so pretty...

Re: Character Inside A Helicopter

Posted: Wed Sep 05, 2012 6:48 am
by Garold
I perceive my helicopter to be real :)

I want to start the game with the helicopter already moving, not from a standstill, currently using the entity mover it increases in speed to match the path intervals. So when the game starts, the character is flung against the inside of the cargo bay. Can I solve this by giving the helicopter and character matching initial velocities?

Re: Character Inside A Helicopter

Posted: Wed Sep 05, 2012 11:12 am
by Garold


I am trying to attach a tailgate to the helicopter.

I lifted code from the robot arm demo. I attach the tailgate to the helicopter using a SwivelHingeJoint. The problem is when I move the helicopter, using an EntityMover, the tailgate is left behind at its original position, it doesn't follow the helicopter. Am I dim?

Code: Select all

            
//Build the helicopter cargo bay
 var bodies = new List<CompoundShapeEntry>() 
{
    // floor
    new CompoundShapeEntry(new BoxShape(2.3f, 0.2f, 9.3f), new Vector3(0, 3, 0), 1),
    // ceiling
    new CompoundShapeEntry(new BoxShape(2.3f, 0.2f, 9.3f), new Vector3(0, 5, 0), 1),
    // back wall
    new CompoundShapeEntry(new BoxShape(2.3f,2f,0.2f),new Vector3(0,4.3f,-4.7f),1),
    // left wall
    new CompoundShapeEntry(new BoxShape(0.2f,2.4f,9.3f), new Vector3(1.25f, 4.1f, 0), 1),
    // right wall
    new CompoundShapeEntry(new BoxShape(0.2f,2.4f,9.3f), new Vector3(-1.25f, 4.1f, 0), 1),
};

     Helicopter = new CompoundBody(bodies);
     Helicopter.Position = new Vector3(250, -6, -250);

     HelicopterTailGate = new Box(Helicopter.Position + new Vector3(0, -1.35f, 7), 2.3f, 0.2f, 2f);

     Space.Add(Helicopter);
     Space.Add(HelicopterTailGate);

     HelicopterTailGateJoint = new SwivelHingeJoint(HelicopterTailGate, Helicopter, HelicopterTailGate.Position + new Vector3(0, 0, -1), Vector3.Right);
     HelicopterTailGateJoint.TwistMotor.IsActive = true;
     HelicopterTailGateJoint.TwistMotor.Settings.Mode = MotorMode.Servomechanism;
     HelicopterTailGateJoint.TwistMotor.Settings.MaximumForce = 1000;
     HelicopterTailGateJoint.HingeMotor.IsActive = true;
     HelicopterTailGateJoint.HingeMotor.Settings.Mode = MotorMode.Servomechanism;
     HelicopterTailGateJoint.HingeMotor.Settings.MaximumForce = 1250;
     HelicopterTailGateJoint.HingeLimit.IsActive = true;
     HelicopterTailGateJoint.HingeLimit.MinimumAngle = -MathHelper.PiOver2;
     HelicopterTailGateJoint.HingeLimit.MaximumAngle = MathHelper.PiOver2;

     Space.Add(HelicopterTailGateJoint);

Re: Character Inside A Helicopter

Posted: Wed Sep 05, 2012 1:23 pm
by Garold
It's OK, I worked it out, all by myself :)

I needed to give the Helicopter and the Tailgate some mass, and it worked fine.

However the character stopped rotating with the helicopter so I had to change an if in CharacterControllerInput

Code: Select all

////Rotate the camera of the character based on the support velocity, if a support with velocity exists.
////This can be very disorienting in some cases; that's why it is off by default!
if (CharacterController.SupportFinder.HasSupport)
{
    SupportData? data;
    if (CharacterController.SupportFinder.HasTraction)
         data = CharacterController.SupportFinder.TractionData;
    else
         data = CharacterController.SupportFinder.SupportData;
    EntityCollidable support = data.Value.SupportObject as EntityCollidable;
    //Having the view turned by dynamic entities is extremely confusing for the most part.
    if (support != null) // && !support.Entity.IsDynamic)
    {
         float dot = Vector3.Dot(support.Entity.AngularVelocity, CharacterController.Body.OrientationMatrix.Up);
         Camera.Yaw += dot * dt;
    }
}

Re: Character Inside A Helicopter

Posted: Wed Sep 05, 2012 4:37 pm
by Norbo
I want to start the game with the helicopter already moving, not from a standstill, currently using the entity mover it increases in speed to match the path intervals. So when the game starts, the character is flung against the inside of the cargo bay. Can I solve this by giving the helicopter and character matching initial velocities?
Yup.
I needed to give the Helicopter and the Tailgate some mass, and it worked fine.
Another option is to just make the tailgate dynamic and keep the helicopter kinematic. At least one of the entities in a constrained pair needs to be dynamic; kinematic entities do not respond to constraints or forces, so constraining two kinematic entities doesn't do much. But, if two dynamic objects works like you want, then there's no need to change things up again :)

Re: Character Inside A Helicopter

Posted: Wed Sep 05, 2012 4:45 pm
by Garold
Thanks Norbo, you are a scholar and a gentleman.

I was complicating the joint too much and getting all sorts of problems, I now do this and it's fine:

Code: Select all

HelicopterTailGateJoint = new RevoluteJoint(HelicopterTailGate, Helicopter, HelicopterTailGate.Position + new Vector3(0, 0, -1), Vector3.Right);
HelicopterTailGateJoint.IsActive = true;
HelicopterTailGateJoint.Motor.IsActive = true;
HelicopterTailGateJoint.Motor.Settings.Mode = MotorMode.Servomechanism;
HelicopterTailGateJoint.Motor.Settings.Servo.Goal = MathHelper.ToRadians(90);
Space.Add(HelicopterTailGateJoint);
When I want to raise or lower the tailgate, I change the Servo.Goal :)

Thanks again!