Treasure Chest

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
vendetta
Posts: 18
Joined: Sat Dec 31, 2011 7:49 pm

Treasure Chest

Post by vendetta »

Hi,
I want to first thank you for the great physics library!
I was using JigLibX, but ran into several problems.
I was able to completely swap it out for bepuPhysics in less than an hour :D

I'm making a dungeon type game, and I want to have treasure chests that the player can open.

Here is a picture of the chest: Image

The chest's body and lid are separate models, so what would be the easiest way to make them attached to each other but still allow for ray picking?

Thanks and have a great new year! :)
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Treasure Chest

Post by Norbo »

I want to first thank you for the great physics library!
Thanks and you're welcome :)
The chest's body and lid are separate models, so what would be the easiest way to make them attached to each other but still allow for ray picking?
If the goal is completely physical behavior, then creating two entities (perhaps convex hulls) and constraining them with a RevoluteJoint would work. The RevoluteJoint.Motor could be used to open the lid, or you could apply grab forces as if your character were opening it with his mouse (like Amnesia, if I remember right).

If you don't want the chest to be tossed around, you can make the base kinematic so it doesn't respond to collisions or forces. The lid can still be dynamic and attached to the kinematic as before.

As everything is physical, raycasts will all work as expected.

Here's an example of setting up the chest and a constraint to connect them, along with the motor approach of opening/closing the lid:

Code: Select all

            Box chestBody = new Box(new Vector3(0, 4, 4), 3, 1.5f, 2, 10);
            Box chestLid = new Box(new Vector3(0, 5f, 4), 3, .5f, 2, 2.5f);
            RevoluteJoint hinge = new RevoluteJoint(chestBody, chestLid, new Vector3(0, 4.75f, 3), Vector3.Right);
            
            //One way to physically open and close the lid is to use the hinge's motor.
            hinge.Motor.IsActive = true;
            hinge.Motor.Settings.Mode = MotorMode.Servomechanism; //The lid has an angle goal as opposed to a velocity goal, so it needs to be a servo.

            //The motor was constructed based on guesses.  Since the hinge anchor offset is offset a bit weirdly,
            //the constraint took a guess that the desired basis would be set up a bit weirdly too.
            //But we don't really want that.  The motor's basis should be aligned with the boxes.
            //For revolute joints, the first vector is the motorized axis.
            //The second vector is the direction of 0 angle.
            //The third vector completes the basis.
            hinge.Motor.Basis.SetWorldAxes(Vector3.Right, Vector3.Forward, Vector3.Up);

            //The test axis is measured against the basis X and Y axes (second and third parameters) to compute the current
            //angle of the connected objects.
            //The basis above can be thought of as being attached to connection A (the body of the chest),
            //while the test axis is attached to connection B (the lid).
            hinge.Motor.TestAxis = Vector3.Forward;

            //By default, the constraint is very, very strong.  It will open quickly and behave rigidly.
            //Make it a bit weaker.
            hinge.Motor.Settings.Servo.SpringSettings.StiffnessConstant /= 100;
            hinge.Motor.Settings.Servo.SpringSettings.DampingConstant /= 100;

            //Add the chest and its connection to the space.
            Space.Add(chestBody);
            Space.Add(chestLid);
            Space.Add(hinge);

            //To close:
            hinge.Motor.Settings.Servo.Goal = 0;

            //To open:
            hinge.Motor.Settings.Servo.Goal = -MathHelper.Pi / 3;
Some alternatives:
If you don't care about physical behavior, you could position the chest's pieces directly for the purposes of queries. Since setting position/orientation directly (teleportation) is unkind to collision response, it would be wise to make the query shapes have no collision and then put a kinematic box that roughly matches the shape of the chest for other dynamic objects to bump into.

It could be even further removed from physics by just placing the objects arbitrarily, but without even putting them in a Space. When the player tries to 'use' something, it would perform a ray cast against these ghost objects or something along those lines.

These alternatives are a little hackier than the pure physical approach, so if you have the computational budget available, I'd probably go for the physical method.
Thanks and have a great new year!
You too :)
Post Reply