2 Possible bugs and a question

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

2 Possible bugs and a question

Post by Danthekilla »

Hey norbo,

I have 2 possible bugs to report :(
Hopefully they are just me doing silly things again.

Anyway the first one is with a entity that ignored another entity and when it touched a static object the simulator would crash with this error. It also had a event attached to the EventHandlerCollisionPairColliding eventmanager.

mscorlib.dll!System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument argument, System.ExceptionResource resource) + 0x41 bytes
> mscorlib.dll!System.Collections.Generic.List<BEPUphysics.Events.EventStorageCollisionPairColliding>.Capacity.set(int value = 4) + 0x23 bytes
mscorlib.dll!System.Collections.Generic.List<BEPUphysics.Events.EventStorageCollisionPairColliding>.EnsureCapacity(int min) + 0x2d bytes
mscorlib.dll!System.Collections.Generic.List<BEPUphysics.Events.EventStorageCollisionPairColliding>.Add(BEPUphysics.Events.EventStorageCollisionPairColliding item) + 0x1d bytes
BEPUphysics.dll!BEPUphysics.EntityEventManager.onCollisionPairUpdated(BEPUphysics.CollisionPair collisionPair = {BEPUphysics.CollisionPair}) + 0x138 bytes
BEPUphysics.dll!BEPUphysics.CollisionPair.updateContactManifold(float dt = 0.02) + 0x120 bytes
BEPUphysics.dll!BEPUphysics.Space.updateCollisionDetectionDiscreteMultithreadedSubFunction(object information = {BEPUphysics.DataStructures.ListIntervalTimestep}) + 0x64 bytes
BEPUphysics.dll!BEPUphysics.ThreadManager.WorkerThread.threadExecutionLoop() + 0x120 bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x66 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x6f bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes

capacity was less than the current size.
Parameter name: value

It didn't happen if the object hit a dynamic object first however...

I have no idea what caused it and i have made work around by making the object in question static for now.

Anyway the other one is more annoying.
I am using a SingleEntityAngularMotor like you suggested to keep a helecoptor upright.
it is starting to work how i want but there is one problem where whenever i change to edit mode (which means all the world objects are re-built and all joints are destroyed) the simulator crashes.

I think i know what this one might be, i was thinking that it could be that the object that the joint was connected too has been removed and somehow the joint is still in the simulator. hence the crash?

Here is the exeption and stack trace


> BEPUphysics.dll!BEPUphysics.Entities.Entity.applySolverAngularImpulse(ref Microsoft.Xna.Framework.Vector3 torque = {X:85.4231 Y:0.002236491 Z:-51.98935}) + 0x71 bytes
BEPUphysics.dll!BEPUphysics.Constraints.SingleEntityAngularMotor.preStep(float dt = 1.99999982E-11) + 0x496 bytes
BEPUphysics.dll!BEPUphysics.Space.preStepSolverUpdateableMultithreadedSubFunction(object information = {BEPUphysics.DataStructures.ListIntervalTimestep}) + 0x9f bytes
BEPUphysics.dll!BEPUphysics.ThreadManager.WorkerThread.threadExecutionLoop() + 0x120 bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x66 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x6f bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes

Object reference not set to an instance of an object.


Anyway its most likely something i'm doing for both of these crashes but i thought i should ask you what you think they could be.


Also i have one other question...
I am trying to use the SingleEntityAngularMotor to keep a helicoptor and a motorbike upright (within reason)

The problem i am having is that a SingleEntityAngularMotor transforms towards a quaternion on all 3 axis when i just want it to try to keep the motorbike up on 1 axis (faceing the direction of the bike) and 2 for the helicopter and plane.

Also how would i control "Lean" for the motorbike and helicoptor? I imagine that i could just change the direction of the desired quaternion but i am still not that great with quaternion's as far as visualizeing them in my head yet...

Also wheels seem to jump whenever they hit a edge of a flat platform (part of a static tri mesh) anyway to reduce this?

Anyway if you have any ideas that would be great.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: 2 Possible bugs and a question

Post by Norbo »

First Error:
This looks to be caused by a missing lock on a couple of the deferred event types (woops!). It's been fixed for v0.14.1; all I'm doing in v0.14.1 is bug fixes and the recapitalization so it shouldn't take too long.

Immediate-suffixed events do not suffer from this issue. If your event handler is thread safe, you could try using them as a workaround.

Second Error:
Your guess was right, that looks to be caused by the SolverUpdateable trying to work on an Entity that no longer belongs to the space.
Also how would i control "Lean" for the motorbike and helicoptor?
If you want one or more angular degrees of freedom to be unrestricted by the constraint, you'll have to use a different kind of constraint. RevoluteMotors control 1 angular DOF; you could use them to control individual axes. TwistMotors also control 1DOF but they compute relative velocity in a slightly different way (which might be useful, or not).

Those constraints are both two-body constraints, but you can connect them to null to simulate being a one-body constraint.

You can also use non-solved semi-constraints, like the UprightSpring in the demos sample code. It just applies a force based on the angle to keep things upright.
Also wheels seem to jump whenever they hit a edge of a flat platform (part of a static tri mesh) anyway to reduce this?
You could try changing the StaticTriangleGroup's useFaceNormalWithinAngle to something above Pi/3. This has some side effects and doesn't fix the issue 100%, but they will be hard to notice in most cases. I have plans for a more 'complete' solution to the intra-mesh triangle boundary in the rewrite.
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

Re: 2 Possible bugs and a question

Post by Danthekilla »

1. Cool this is good :)
2. Cool i will try to get the joint removed when the body removes itself

3. Ahh i thought that only the single entity constraints would work... yer a few revolute joints should work :)
4. I will try this.

Thanks for all you help.
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

Re: 2 Possible bugs and a question

Post by Danthekilla »

I managed to fix issue 2.
Im still working on issue 3
i tried the "Fix" for the 4th issue but it didnt seem to do anything. I tried 6 different values from pi/3 to 2pi.
(pi/2 was a little better so i left it at that)

Anyway thanks, i just thought i would give you an update.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: 2 Possible bugs and a question

Post by Norbo »

FYI, (and for anyone else that's curious) The 'fix' given for #4 is more or less a hack that forces contact normals to align with triangle normals, but when a wheel passes over a triangle boundary, new contacts must be created. These usually have a slightly different height even if the normal hasn't changed, which can push rolling or sliding things off course a little.

When contact normals aren't aligned, you see a much more defined bump between triangles since the normal can point against the motion of the sliding object. The hack addresses these, but not the small height-bumps.

The new collision system will let the collision handler see adjacent triangles and make adjustments to contact depth/normal without resorting to hacks, so theoretically it can support much smoother internal borders.
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

Re: 2 Possible bugs and a question

Post by Danthekilla »

Thats fair enough,

I managed to get a twistmotor to keep my bike upwards but it only seems to do so when it is aiming in the direction it was created, the more it points in the other direction the less its holds it up

here is a video (sorry for the terrible quality i uploaded it wrong)

http://www.youtube.com/watch?v=c9D1gRhSCKQ

it seems to hold up the bike less and less as it points in the opposite direction.

Any ideas?

Here is the code i use
//We are a bike and should try to keep upright :)
KeepUp = new TwistMotor(MainAttachedPart, null, Vector3.Transform(Vector3.Forward, LastAddedBody.orientationQuaternion), Vector3.Transform(Vector3.Forward, LastAddedBody.orientationQuaternion));
KeepUp.settings.mode = MotorMode.servomechanism;
KeepUp.settings.servo.goal = 0;
KeepUp.settings.servo.springSettings.stiffnessConstant = 500000;
KeepUp.settings.servo.springSettings.dampingConstant = 200000;
KeepUp.settings.maximumForce = 5000;
KeepUp.isActive = true;
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

Re: 2 Possible bugs and a question

Post by Danthekilla »

One other question, what would the best way be to detect inital collisions and constant collsions with a fluid volume?
The floatingBodies list inside it is internal, so how else could i obtain the info i need?

Would it be possible for you to make that have a get property or function in 14.1?

Thanks.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: 2 Possible bugs and a question

Post by Norbo »

Here's an example implementation using a RevoluteMotor. I used it instead of TwistMotor since I find it a little easier to configure in this instance.

It's a bit ugly since the second connection's test axis has to be managed (since it's a two-body constraint).

Code: Select all

            //Create the 'motorcycle'
            motorcycleBox = new Box(Vector3.Zero, 1, 3, 4, 100);

            space.add(motorcycleBox);

            //Create and configure the constraint.
            //The constraint might guess a configuration that works,
            //but this just sets it for clarity.
            KeepUp = new RevoluteMotor(motorcycleBox, null, motorcycleBox.orientationMatrix.Forward);
            KeepUp.basis.setWorldAxes(motorcycleBox.orientationMatrix.Backward, motorcycleBox.orientationMatrix.Right, motorcycleBox.orientationMatrix.Up);

            KeepUp.settings.mode = MotorMode.servomechanism;
            KeepUp.settings.servo.goal = 0;
            KeepUp.settings.servo.springSettings.stiffnessConstant = 20000;
            KeepUp.settings.servo.springSettings.dampingConstant = 10000;

            space.add(KeepUp);

...
In the Update:

            //Compute the testAxis attached to the world space entity.
            //This projects the restricted axis of the motorcycle onto the horizontal plane,
            //then rotates it 90 degrees so that it can be used to measure the angle.
            Vector3 horizontalDirection = motorcycleBox.orientationMatrix.Backward;
            horizontalDirection.Y = 0;
            float lengthSquared = horizontalDirection.LengthSquared();
            if (lengthSquared > Toolbox.bigEpsilon)
                horizontalDirection /= (float)Math.Sqrt(lengthSquared);
            else
                horizontalDirection = motorcycleBox.orientationMatrix.Backward;
            horizontalDirection = Vector3.TransformNormal(horizontalDirection, Matrix.CreateRotationY(MathHelper.PiOver2));

            KeepUp.testAxis = horizontalDirection;

You could rewrite the UprightSpring to do something similar, too.
One other question, what would the best way be to detect inital collisions and constant collsions with a fluid volume?
The floatingBodies list inside it is internal, so how else could i obtain the info i need?

Would it be possible for you to make that have a get property or function in 14.1?
The FluidVolume handles its entities awkwardly (and is on the list of things to be rewritten from the ground up). I'll look into it, but I'd recommend using a separate DetectorVolume in the interim. It robustly supports events and containment tests.
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

Re: 2 Possible bugs and a question

Post by Danthekilla »

Cool thanks for the help.
Ill try get them both working tommrow morning.

Thanks.
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

Re: 2 Possible bugs and a question

Post by Danthekilla »

Ok so i tryed putting in the code you figured out for me and i cannot figure out why its not working.
With the code you sent me the revolute motor seems to always be trying to spin to some angle and it never reaches it so it just goes crazy.

I thought i would just put together a little bike so i can show you how it works, (Also the physics is a near perfect match to the visuals, built entirly from boxes and cylinders in compund bodys)

I want the direction of the bike seat (we have an artist making a very cool looking seat as we speak) to dictate the angle that the bike trys to stay up on.
The wheels are made from a box and a cynider that ignore each other combined with 2 revolute joints for turning and driving the wheels.

All seperate objects attach to each other at the end of the edit stage and then before the first update in the running stage i do the extra things like creating the joints required etc...

Here is a picture with the parts labled of how i use them incase it helps you get where im going with it.

And here is the code that i use in the post edit mode startup (when you try to run the level) which creates joints for attached objects etc...
MainAttachedPart is the object (in this case the bike body) that the seat is attached to during the edit stage.

Code: Select all

public override void PostWorldBuildStartup()
        {
            base.PostWorldBuildStartup();

            //We are a bike and should try to keep upright :)
            if (MainAttachedPart != null)
            {
                KeepUp = new RevoluteMotor(MainAttachedPart, null, MainAttachedPart.orientationMatrix.Forward);
                KeepUp.basis.setWorldAxes(MainAttachedPart.orientationMatrix.Backward, MainAttachedPart.orientationMatrix.Right, MainAttachedPart.orientationMatrix.Up);

                KeepUp.settings.mode = MotorMode.servomechanism;
                KeepUp.settings.servo.goal = 0f;
                KeepUp.settings.servo.springSettings.stiffnessConstant = 20000;
                KeepUp.settings.servo.springSettings.dampingConstant = 10000;
                KeepUp.isActive = true;

                Constrants.Add(KeepUp);
                g_EntityManager.GET.space.add(KeepUp);
            }
        }
And here is the update for the object

Code: Select all


        public override void Update(GameTime in_GameTime)
        {
            if (KeepUp != null && MainAttachedPart != null)
            {
                //Compute the testAxis attached to the world space entity.
                //This projects the restricted axis of the motorcycle onto the horizontal plane,
                //then rotates it 90 degrees so that it can be used to measure the angle.
                Vector3 horizontalDirection = MainAttachedPart.orientationMatrix.Backward;
                horizontalDirection.Y = 0;
                float lengthSquared = horizontalDirection.LengthSquared();
                if (lengthSquared > Toolbox.bigEpsilon)
                    horizontalDirection /= (float)Math.Sqrt(lengthSquared);
                else
                    horizontalDirection = MainAttachedPart.orientationMatrix.Backward;
                horizontalDirection = Vector3.TransformNormal(horizontalDirection, Matrix.CreateRotationY(MathHelper.PiOver2));

                KeepUp.testAxis = horizontalDirection;
            }
        }
Image



On the plus side i have the water and water collision detection working pretty well now :) (and the graphics for the water are also great)
Anyway sorry to be a bother but i just can't get this to work properly so it holds up the bike...
Can you see me doing anything wrong, am i going about it the wrong way?

Thanks
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: 2 Possible bugs and a question

Post by Norbo »

I don't see anything obviously different or wrong, but as a sanity check, what does it do if you set it up using the "motorcycleBox" entity from my example instead? If using the motorcycleBox works, it may be the way in which the "MainAttachedPart" is oriented. For example, even though it appears to be aligned, its "Backward" may be more like "Up," which would cause it to do wonky things.

You can check the motor's error property to see how much error it is detecting. If it is converging to zero and still looks wrong, that supports the bad orientation/configuration idea. If the error flying around all over the place, it could be fighting another constraint or it isn't strong enough to right itself, though the orientation/configuration still might be wrong.
Post Reply