Discuss any questions about BEPUphysics or problems encountered.
			
		
		
			
				
																			
								BrianL 							 
									
		Posts:  54 Joined:  Wed Jun 25, 2008 4:41 pmLocation:  Panama City Beach, FL 
		
						
					
													
							
						
									
						Post 
					 
								by BrianL  Sun Jun 29, 2008 9:28 pm 
			
			
			
			
			
			I'm using a MaximumSpeedConstraint in my scene.  After a few seconds at high speed I can reliably get it to crash 100% of the time with the following call stack.  The test is being run with a Box and StaticTriangleGroup with the Box as the moving Entity. Looks like some vectors are becoming invalid...possibly due to the constraint's interaction?
Code: Select all 
mscorlib.dll!System.Math.Sign(float value = NaN) + 0x23 bytes	
BEPUphysics.dll!BEPUphysics.Box.getExtremePoint(ref Microsoft.Xna.Framework.Vector3 d = {X:-1 Y:0 Z:0}, float margin = 0.04, ref Microsoft.Xna.Framework.Vector3 linearVelocity = {X:NaN Y:NaN Z:NaN}, ref Microsoft.Xna.Framework.Vector3 backwardLinearVelocity = {X:NaN Y:NaN Z:NaN}) + 0x17 bytes	
BEPUphysics.dll!BEPUphysics.Entity.getExtremePoints(ref Microsoft.Xna.Framework.Vector3 d = {X:1 Y:0 Z:0}, out Microsoft.Xna.Framework.Vector3 min = {X:0 Y:0 Z:0}, out Microsoft.Xna.Framework.Vector3 max = {X:0 Y:0 Z:0}, float margin = 0.04, ref Microsoft.Xna.Framework.Vector3 linearVelocity = {X:NaN Y:NaN Z:NaN}, ref Microsoft.Xna.Framework.Vector3 backwardLinearVelocity = {X:NaN Y:NaN Z:NaN}) + 0x1b bytes	
BEPUphysics.dll!BEPUphysics.Entity.findBoundingBox(ref Microsoft.Xna.Framework.Vector3 linearVelocity = {X:NaN Y:NaN Z:NaN}, ref Microsoft.Xna.Framework.Vector3 backwardLinearVelocity = {X:NaN Y:NaN Z:NaN}) + 0x17 bytes	
BEPUphysics.dll!BEPUphysics.Space.update(float dt = 0.0166667, float timeSinceLastFrame = 0.0168094635) + 0x58a bytes	
BEPUphysics.dll!BEPUphysics.Space.update(Microsoft.Xna.Framework.GameTime gameTime = {Microsoft.Xna.Framework.GameTime}) + 0x42 bytes	
 
		 
				
		
		 
	 
				
		
		
			
				
								Zukarakox 							 
						Not a Site Admin 			
		Posts:  426 Joined:  Mon Jul 10, 2006 4:28 am 
		
						
					
													
							
						
									
						Post 
					 
								by Zukarakox  Sun Jun 29, 2008 9:49 pm 
			
			
			
			
			
			YOU BROKEEE ITTTT....
			
			
									
						
							i has multiple toes
			
						 
		 
				
		
		 
	 
				
		
		
			
				
																			
								Norbo 							 
						Site Admin 			
		Posts:  4929 Joined:  Tue Jul 04, 2006 4:45 am 
		
						
					
													
							
						
									
						Post 
					 
								by Norbo  Sun Jun 29, 2008 9:52 pm 
			
			
			
			
			
			Could you create a little reproduction setup for this error?  
			
			
									
						
										
						 
		 
				
		
		 
	 
				
		
		
			
				
																			
								BrianL 							 
									
		Posts:  54 Joined:  Wed Jun 25, 2008 4:41 pmLocation:  Panama City Beach, FL 
		
						
					
													
							
						
									
						Post 
					 
								by BrianL  Sun Jun 29, 2008 10:48 pm 
			
			
			
			
			
			No, I'm not setting anything related to the inertia tensor of the box.  Simply calling Box.applyImpulse each frame to accelerate the cube.  I was procedurally rotating the linearMomentum vector but have disabled all of that in an attempt to pinpoint a possible culprit.  However, none of that has helped so far.  At this point, I've reduced it to Box.applyImpulse calls and Box.rotate calls for the update loop. I did have the maximumAngularSpeed set to 0.0f on the MaximumSpeedConstraint, so I tried setting it to some positive value.  Didn't help.
			
			
									
						
										
						 
		 
				
		
		 
	 
				
		
		
			
				
																			
								Norbo 							 
						Site Admin 			
		Posts:  4929 Joined:  Tue Jul 04, 2006 4:45 am 
		
						
					
													
							
						
									
						Post 
					 
								by Norbo  Mon Jun 30, 2008 12:17 am 
			
			
			
			
			
			I am not 100% sure, but I think it would require the whole solution for deployment purposes.
			
			
									
						
										
						 
		 
				
		
		 
	 
				
		
		
			
				
																			
								BrianL 							 
									
		Posts:  54 Joined:  Wed Jun 25, 2008 4:41 pmLocation:  Panama City Beach, FL 
		
						
					
													
							
						
									
						Post 
					 
								by BrianL  Mon Jun 30, 2008 3:11 am 
			
			
			
			
			
			Okay, I've got assertions checking just about every component of every vector or matrix (that I have access to) that can change at the Entity level...and nothing is getting hit.  Here's the state of the cube at the time of the crash:
I see that some of the "my" and "previous" member variables are also NaN...
Code: Select all 
-		m_Cube	{BEPUphysics.Box}	BEPUphysics.Box
-		base	{BEPUphysics.Box}	BEPUphysics.Entity {BEPUphysics.Box}
		allowedPenetration	0.025	float
		angularDamping	0.75	float
+		angularMomentum	{X:NaN Y:NaN Z:NaN}	Microsoft.Xna.Framework.Vector3
+		angularVelocity	{X:81.73529 Y:-97.50146 Z:5.956311}	Microsoft.Xna.Framework.Vector3
		bounciness	0.0	float
+		boundingBox	{Min:{X:-3.158347 Y:40.80492 Z:250.8726} Max:{X:5.326904 Y:49.29885 Z:255.7614}}	Microsoft.Xna.Framework.BoundingBox
+		centerPosition	{X:1.084278 Y:45.05188 Z:253.317}	Microsoft.Xna.Framework.Vector3
		collisionFilter	18446744073709551615	ulong
		collisionMargin	0.04	float
		compoundActivity	true	bool
+		compoundAngularMomentum	{X:NaN Y:NaN Z:NaN}	Microsoft.Xna.Framework.Vector3
+		compoundAngularVelocity	{X:NaN Y:NaN Z:NaN}	Microsoft.Xna.Framework.Vector3
		compoundBody	null	BEPUphysics.CompoundBody
+		compoundCorrectiveAngularVelocity	{X:0 Y:0 Z:0}	Microsoft.Xna.Framework.Vector3
+		compoundCorrectiveLinearVelocity	{X:0 Y:0 Z:0}	Microsoft.Xna.Framework.Vector3
+		compoundInertiaTensorInverse	{ {M11:0.02026436 M12:-0.001954478 M13:-0.0008725619 M14:0} {M21:-0.001954478 M22:0.01064112 M23:-0.001182511 M24:0} {M31:-0.000872562 M32:-0.001182512 M33:0.01140407 M34:0} {M41:0 M42:0 M43:0 M44:0.9999999} }	Microsoft.Xna.Framework.Matrix
+		compoundLinearMomentum	{X:1634.706 Y:-1950.029 Z:119.1262}	Microsoft.Xna.Framework.Vector3
+		compoundLinearVelocity	{X:81.73529 Y:-97.50146 Z:5.956311}	Microsoft.Xna.Framework.Vector3
		compoundMass	20.0	float
+		compoundOrientationQuaternion	{X:NaN Y:NaN Z:NaN W:NaN}	Microsoft.Xna.Framework.Quaternion
+		compoundPosition	{X:1.084278 Y:45.05188 Z:253.317}	Microsoft.Xna.Framework.Vector3
+		compoundRotationMatrix	{ {M11:NaN M12:NaN M13:NaN M14:0} {M21:NaN M22:NaN M23:NaN M24:0} {M31:NaN M32:NaN M33:NaN M34:0} {M41:0 M42:0 M43:0 M44:1} }	Microsoft.Xna.Framework.Matrix
+		constraints	{System.Collections.Generic.List<BEPUphysics.Constraint>}	System.Collections.Generic.List<BEPUphysics.Constraint>
+		controllers	{System.Collections.Generic.List<BEPUphysics.Controller>}	System.Collections.Generic.List<BEPUphysics.Controller>
+		correctiveAngularVelocity	{X:0 Y:0 Z:0}	Microsoft.Xna.Framework.Vector3
+		correctiveLinearVelocity	{X:0 Y:0 Z:0}	Microsoft.Xna.Framework.Vector3
		density	0.8333333	float
+		force	{X:54.90942 Y:18.10596 Z:-36.97366}	Microsoft.Xna.Framework.Vector3
+		forces	{System.Collections.Generic.List<BEPUphysics.Force>}	System.Collections.Generic.List<BEPUphysics.Force>
		framesBelowAngularVelocityThreshold	0	int
		framesBelowLinearVelocityThreshold	0	int
		friction	0.3	float
+		inertiaTensorInverse	{ {M11:0.02026436 M12:-0.001954478 M13:-0.0008725619 M14:0} {M21:-0.001954478 M22:0.01064112 M23:-0.001182511 M24:0} {M31:-0.000872562 M32:-0.001182512 M33:0.01140407 M34:0} {M41:0 M42:0 M43:0 M44:0.9999999} }	Microsoft.Xna.Framework.Matrix
		internalIterationFlag	0	byte
		isActive	true	bool
		isAffectedByGravity	true	bool
		isAlwaysActive	false	bool
		isDeactivationCandidate	false	bool
		isMemberOfRayCastableContainer	false	bool
		isPhysicallySimulated	true	bool
		isSubBodyOfCompound	false	bool
		isTangible	true	bool
		linearDamping	0.0	float
+		linearMomentum	{X:1634.706 Y:-1950.029 Z:119.1262}	Microsoft.Xna.Framework.Vector3
+		linearVelocity	{X:81.73529 Y:-97.50146 Z:5.956311}	Microsoft.Xna.Framework.Vector3
+		localInertiaTensor	{ {M11:81.66667 M12:0 M13:0 M14:0} {M21:0 M22:106.6667 M23:0 M24:0} {M31:0 M32:0 M33:48.33334 M34:0} {M41:0 M42:0 M43:0 M44:1} }	Microsoft.Xna.Framework.Matrix
+		localInertiaTensorInverse	{ {M11:0.0122449 M12:0 M13:0 M14:0} {M21:0 M22:0.009374999 M23:0 M24:0} {M31:0 M32:0 M33:0.02068965 M34:0} {M41:0 M42:0 M43:0 M44:0.9999999} }	Microsoft.Xna.Framework.Matrix
+		localSpaceInertiaTensor	{ {M11:81.66667 M12:0 M13:0 M14:0} {M21:0 M22:106.6667 M23:0 M24:0} {M31:0 M32:0 M33:48.33334 M34:0} {M41:0 M42:0 M43:0 M44:1} }	Microsoft.Xna.Framework.Matrix
		margin	0.04	float
		marginSquared	0.0016	float
		mass	20.0	float
+		myAngularVelocity	{X:NaN Y:NaN Z:NaN}	Microsoft.Xna.Framework.Vector3
+		myLinearVelocity	{X:81.73529 Y:-97.50146 Z:5.956311}	Microsoft.Xna.Framework.Vector3
+		mySpace	{BEPUphysics.Space}	BEPUphysics.Space
+		nonCollidableEntities	{System.Collections.Generic.List<BEPUphysics.Entity>}	System.Collections.Generic.List<BEPUphysics.Entity>
+		orientation	{X:NaN Y:NaN Z:NaN W:NaN}	Microsoft.Xna.Framework.Quaternion
+		orientationQuaternion	{X:NaN Y:NaN Z:NaN W:NaN}	Microsoft.Xna.Framework.Quaternion
+		position	{X:1.084278 Y:45.05188 Z:253.317}	Microsoft.Xna.Framework.Vector3
+		previousAngularMomentum	{X:NaN Y:NaN Z:NaN}	Microsoft.Xna.Framework.Vector3
+		previousLinearMomentum	{X:1634.706 Y:-1950.029 Z:119.1262}	Microsoft.Xna.Framework.Vector3
+		rotation	{ {M11:NaN M12:NaN M13:NaN M14:0} {M21:NaN M22:NaN M23:NaN M24:0} {M31:NaN M32:NaN M33:NaN M34:0} {M41:0 M42:0 M43:0 M44:1} }	Microsoft.Xna.Framework.Matrix
+		rotationMatrix	{ {M11:NaN M12:NaN M13:NaN M14:0} {M21:NaN M22:NaN M23:NaN M24:0} {M31:NaN M32:NaN M33:NaN M34:0} {M41:0 M42:0 M43:0 M44:1} }	Microsoft.Xna.Framework.Matrix
+		simulationIsland	{BEPUphysics.SimulationIsland}	BEPUphysics.SimulationIsland
+		space	{BEPUphysics.Space}	BEPUphysics.Space
		tag	null	object
+		torque	{X:NaN Y:NaN Z:NaN}	Microsoft.Xna.Framework.Vector3
+		totalForce	{X:54.90942 Y:18.10596 Z:-36.97366}	Microsoft.Xna.Framework.Vector3
+		totalTorque	{X:NaN Y:NaN Z:NaN}	Microsoft.Xna.Framework.Vector3
		useContinuousDetection	true	bool
		useOneShotManifolds	true	bool
		volume	24.0	float
		halfHeight	0.5	float
		halfLength	3.0	float
		halfWidth	2.0	float
		height	1.0	float
		length	6.0	float
		width	4.0	float
 
		 
				
		
		 
	 
				
		
		
			
				
																			
								Norbo 							 
						Site Admin 			
		Posts:  4929 Joined:  Tue Jul 04, 2006 4:45 am 
		
						
					
													
							
						
									
						Post 
					 
								by Norbo  Mon Jun 30, 2008 6:17 am 
			
			
			
			
			
			I managed to find the source; it was just an issue with the normalization of velocities eventually resulting in infinities due to the extremely small values involved (I probably should have noticed that sooner 
).  Unfortunately this can't be fixed externally, but it's pretty simple and can work as an example of using the constraint framework so I'll go ahead and release the source code:
Code: Select all 
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using System.Diagnostics;
namespace BEPUphysics
{
    /// <summary>
    /// Prevents the target entity from moving faster than the specified speeds.
    /// </summary>
    public class MaximumSpeedConstraint:SingleBodyConstraint
    {
        /// <summary>
        /// Maximum linear speed allowed.
        /// </summary>
        public float maximumLinearSpeed;
        /// <summary>
        /// Maximum angular speed allowed.
        /// </summary>
        public float maximumAngularSpeed;
        Vector3 linearVelocityDirection;
        Vector3 angularVelocityDirection;
        Matrix inertiaTensor;
        /// <summary>
        /// Constructs a maximum speed constraint.
        /// </summary>
        /// <param name="e">Entity to target.</param>
        /// <param name="maxLinearSpeed">Maximum linear speed allowed.</param>
        /// <param name="maxAngularSpeed">Maximum angular speed allowed.</param>
        public MaximumSpeedConstraint(Entity e, float maxLinearSpeed, float maxAngularSpeed)
        {
            entity = e;
            maximumLinearSpeed = maxLinearSpeed;
            maximumAngularSpeed = maxAngularSpeed;
        }
        /// <summary>
        /// Calculates necessary information for velocity solving.
        /// Called automatically by space.
        /// </summary>
        /// <param name="dt">Time in seconds since the last update.</param>
        public override void preStep(float dt)
        {
            float linearVelocityMagnitudeSquared = entity.linearVelocity.LengthSquared();
            if (linearVelocityMagnitudeSquared > 1E-40f)
                linearVelocityDirection = entity.linearVelocity / (float)Math.Sqrt(linearVelocityMagnitudeSquared);
            else
                linearVelocityDirection = Vector3.Zero;
            float angularVelocityMagnitudeSquared = entity.angularVelocity.LengthSquared();
            if (angularVelocityMagnitudeSquared > 1E-40f)
                angularVelocityDirection = entity.angularVelocity / (float)Math.Sqrt(angularVelocityMagnitudeSquared);
            else
                angularVelocityDirection = Vector3.Zero;
            inertiaTensor = Matrix.Invert(entity.inertiaTensorInverse);
        }
        /// <summary>
        /// Calculates and applies corrective impulses.
        /// Called automatically by space.
        /// </summary>
        /// <param name="dt">Time in seconds since the last update.</param>
        public override void applyImpulse(float dt)
        {
            float linearVelocity = Vector3.Dot(entity.myLinearVelocity, linearVelocityDirection);
            if (linearVelocity > maximumLinearSpeed)
            {
                float diff = maximumLinearSpeed - linearVelocity;
                Vector3 linearImpulse = (diff * entity.mass) * linearVelocityDirection;
                entity.linearMomentum += linearImpulse;
                entity.myLinearVelocity = entity.linearMomentum / entity.mass;
            }
            float angularVelocity = Vector3.Dot(entity.myAngularVelocity, angularVelocityDirection);
            if (angularVelocity > maximumAngularSpeed)
            {
                float diff = maximumAngularSpeed - angularVelocity;
                Vector3 angularImpulse = Vector3.Transform(diff * angularVelocityDirection, inertiaTensor);
                entity.angularMomentum += angularImpulse;
                entity.myAngularVelocity = Vector3.Transform(entity.angularMomentum, entity.inertiaTensorInverse);
            }
        }
    }
}
The above source is made available under the same permissive zlib-style license as the demos, which can be found at 
http://www.bepu-games.com/BEPUphysics/demoslicense.txt .
 
		 
				
		
		 
	 
				
		
		
			
				
																			
								BrianL 							 
									
		Posts:  54 Joined:  Wed Jun 25, 2008 4:41 pmLocation:  Panama City Beach, FL 
		
						
					
													
							
						
									
						Post 
					 
								by BrianL  Mon Jun 30, 2008 1:12 pm 
			
			
			
			
			
			Awesome.  Thank you very much for taking the time to look through it and ultimately finding what the problem was/is.
Edit:
The following function doesn't have access to the "myLinearVelocity" and "myAngularVelocity" member variables, unless I'm just missing some silly C#-ism.  I tried using just linearVelocity and angularVelocity instead, but the visual results are telling me that the two are not the same internally. 
Code: Select all 
public override void applyImpulse(float dt)
        {
            float linearVelocity = Vector3.Dot(entity.myLinearVelocity, linearVelocityDirection);
            if (linearVelocity > maximumLinearSpeed)
            {
                float diff = maximumLinearSpeed - linearVelocity;
                Vector3 linearImpulse = (diff * entity.mass) * linearVelocityDirection;
                entity.linearMomentum += linearImpulse;
                entity.myLinearVelocity = entity.linearMomentum / entity.mass;
            }
            float angularVelocity = Vector3.Dot(entity.myAngularVelocity, angularVelocityDirection);
            if (angularVelocity > maximumAngularSpeed)
            {
                float diff = maximumAngularSpeed - angularVelocity;
                Vector3 angularImpulse = Vector3.Transform(diff * angularVelocityDirection, inertiaTensor);
                entity.angularMomentum += angularImpulse;
                entity.myAngularVelocity = Vector3.Transform(entity.angularMomentum, entity.inertiaTensorInverse);
            }
        }
 
		 
				
		
		 
	 
				
		
		
			
				
																			
								Norbo 							 
						Site Admin 			
		Posts:  4929 Joined:  Tue Jul 04, 2006 4:45 am 
		
						
					
													
							
						
									
						Post 
					 
								by Norbo  Mon Jun 30, 2008 7:11 pm 
			
			
			
			
			
			Sorry about that, forgot about the ridiculous bug I had fixed that causes the angularVelocity property to get the 
linear Velocity.  Here's a workaround for the applyImpulse method, since setting the property still works in v0.5.2.
Code: Select all 
        /// <summary>
        /// Calculates and applies corrective impulses.
        /// Called automatically by space.
        /// </summary>
        /// <param name="dt">Time in seconds since the last update.</param>
        public override void applyImpulse(float dt)
        {
            float linearVelocity = Vector3.Dot(entity.linearVelocity, linearVelocityDirection);
            if (linearVelocity > maximumLinearSpeed)
            {
                float diff = maximumLinearSpeed - linearVelocity;
                Vector3 linearImpulse = (diff * entity.mass) * linearVelocityDirection;
                entity.linearMomentum += linearImpulse;
                entity.linearVelocity = entity.linearMomentum / entity.mass;
            }
            float angularVelocity = Vector3.Dot(Vector3.Transform(entity.angularMomentum, entity.inertiaTensorInverse), angularVelocityDirection);
            if (angularVelocity > maximumAngularSpeed)
            {
                float diff = maximumAngularSpeed - angularVelocity;
                Vector3 angularImpulse = Vector3.Transform(diff * angularVelocityDirection, inertiaTensor);
                entity.angularVelocity = Vector3.Transform(Vector3.Transform(entity.angularMomentum + angularImpulse, entity.inertiaTensorInverse), entity.inertiaTensorInverse);
            }
        } 
		 
				
		
		 
	 
				
		
		
			
				
																			
								BrianL 							 
									
		Posts:  54 Joined:  Wed Jun 25, 2008 4:41 pmLocation:  Panama City Beach, FL 
		
						
					
													
							
						
									
						Post 
					 
								by BrianL  Mon Jun 30, 2008 7:36 pm 
			
			
			
			
			
			Ha!  Yeah, that's the behavior I was seeing.  The angularVelocity was somehow ending up with the linearVelocity.  LOL  It's all good.  Thanks for the workaround.  I'll either try it tonight or in the morning and report back.
Norbo wrote: Sorry about that, forgot about the ridiculous bug I had fixed that causes the angularVelocity property to get the linear Velocity.  Here's a workaround for the applyImpulse method, since setting the property still works in v0.5.2.
 
		 
				
		
		 
	 
				
		
		
			
				
																			
								BrianL 							 
									
		Posts:  54 Joined:  Wed Jun 25, 2008 4:41 pmLocation:  Panama City Beach, FL 
		
						
					
													
							
						
									
						Post 
					 
								by BrianL  Tue Jul 01, 2008 1:12 pm 
			
			
			
			
			
			So far so good on the fix.  Thanks.