private void CreateScene0() { // Newton was here BoxObject holder = new BoxObject(this, boxModel, new Vector3(5, 1, 1), Matrix.Identity, new Vector3(-10, -5, 5)); holder.PhysicsBody.Immovable = true; this.Components.Add(holder); for (int i = 0; i < 5; i++) { SphereObject obj = new SphereObject(this, sphereModel, 0.5f, Matrix.Identity, new Vector3(-12 + i, -8, 5)); obj.PhysicsBody.CollisionSkin.SetMaterialProperties(0, new MaterialProperties(1.0f, 0.2f, 0.2f)); obj.PhysicsBody.AllowFreezing = false; ConstraintMaxDistance maxDist1 = new ConstraintMaxDistance(holder.PhysicsBody, new Vector3(-2 + i, -0.5f, 0.5f), obj.PhysicsBody, Vector3.Up * 0.5f, 3f); ConstraintMaxDistance maxDist2 = new ConstraintMaxDistance(holder.PhysicsBody, new Vector3(-2 + i, -0.5f, -0.5f), obj.PhysicsBody, Vector3.Up * 0.5f, 3f); maxDist1.EnableConstraint(); maxDist2.EnableConstraint(); this.Components.Add(obj); if (i == 4) obj.PhysicsBody.MoveTo(new Vector3(-6, -6, 5), Matrix.Identity); if (i == 3) obj.PhysicsBody.MoveTo(new Vector3(-7, -6, 5), Matrix.Identity); } }
/// <summary> /// Initialise /// </summary> /// <param name="body0"></param> /// <param name="body1"></param> /// <param name="hingeAxis"></param> /// <param name="hingePosRel0"></param> /// <param name="hingeHalfWidth"></param> /// <param name="hingeFwdAngle"></param> /// <param name="hingeBckAngle"></param> /// <param name="sidewaysSlack"></param> /// <param name="damping"></param> public void Initialise(Body body0, Body body1, Vector3 hingeAxis, Vector3 hingePosRel0, float hingeHalfWidth, float hingeFwdAngle, float hingeBckAngle, float sidewaysSlack, float damping) { this.body0 = body0; this.body1 = body1; this.hingeAxis = hingeAxis; this.hingePosRel0 = hingePosRel0; this.usingLimit = false; this.damping = damping; // tScalar allowedDistance = 0.005f; this.hingeAxis.Normalize(); Vector3 hingePosRel1 = body0.Position + hingePosRel0 - body1.Position; // generate the two positions relative to each body Vector3 relPos0a = hingePosRel0 + hingeHalfWidth * hingeAxis; Vector3 relPos0b = hingePosRel0 - hingeHalfWidth * hingeAxis; Vector3 relPos1a = hingePosRel1 + hingeHalfWidth * hingeAxis; Vector3 relPos1b = hingePosRel1 - hingeHalfWidth * hingeAxis; float timescale = 1.0f / 20.0f; float allowedDistanceMid = 0.005f; float allowedDistanceSide = sidewaysSlack * hingeHalfWidth; mSidePointConstraints = new ConstraintMaxDistance[2]; mSidePointConstraints[0] = new ConstraintMaxDistance(); mSidePointConstraints[1] = new ConstraintMaxDistance(); mSidePointConstraints[0].Initialise(body0, relPos0a, body1, relPos1a, allowedDistanceSide); mSidePointConstraints[1].Initialise(body0, relPos0b, body1, relPos1b, allowedDistanceSide); mMidPointConstraint = new ConstraintPoint(); mMidPointConstraint.Initialise(body0, hingePosRel0, body1, hingePosRel1, allowedDistanceMid, timescale); if (hingeFwdAngle <= 150) // MAX_HINGE_ANGLE_LIMIT { // choose a direction that is perpendicular to the hinge Vector3 perpDir = Vector3.Up; if (Vector3.Dot(perpDir, hingeAxis) > 0.1f) { perpDir = Vector3.Right; } // now make it perpendicular to the hinge Vector3 sideAxis = Vector3.Cross(hingeAxis, perpDir); perpDir = Vector3.Cross(sideAxis, hingeAxis); perpDir.Normalize(); // the length of the "arm" TODO take this as a parameter? what's // the effect of changing it? float len = 10.0f * hingeHalfWidth; // Choose a position using that dir. this will be the anchor point // for body 0. relative to hinge Vector3 hingeRelAnchorPos0 = perpDir * len; // anchor point for body 2 is chosen to be in the middle of the // angle range. relative to hinge float angleToMiddle = 0.5f * (hingeFwdAngle - hingeBckAngle); Vector3 hingeRelAnchorPos1 = Vector3.TransformNormal(hingeRelAnchorPos0, Matrix.CreateFromAxisAngle(hingeAxis, MathHelper.ToRadians(-angleToMiddle))); // work out the "string" length float hingeHalfAngle = 0.5f * (hingeFwdAngle + hingeBckAngle); float allowedDistance = len * 2.0f * (float)System.Math.Sin(MathHelper.ToRadians(hingeHalfAngle * 0.5f)); Vector3 hingePos = body1.Position + hingePosRel0; Vector3 relPos0c = hingePos + hingeRelAnchorPos0 - body0.Position; Vector3 relPos1c = hingePos + hingeRelAnchorPos1 - body1.Position; mMaxDistanceConstraint = new ConstraintMaxDistance(); mMaxDistanceConstraint.Initialise(body0, relPos0c, body1, relPos1c, allowedDistance); usingLimit = true; } if (damping <= 0.0f) { damping = -1.0f; // just make sure that a value of 0.0 doesn't mess up... } else { damping = MathHelper.Clamp(damping, 0, 1); } }
/// <summary> /// Initialise /// </summary> /// <param name="body0"></param> /// <param name="body1"></param> /// <param name="hingeAxis"></param> /// <param name="hingePosRel0"></param> /// <param name="hingeHalfWidth"></param> /// <param name="hingeFwdAngle"></param> /// <param name="hingeBckAngle"></param> /// <param name="sidewaysSlack"></param> /// <param name="damping"></param> public void Initialise(Body body0, Body body1, Vector3 hingeAxis, Vector3 hingePosRel0, float hingeHalfWidth, float hingeFwdAngle, float hingeBckAngle, float sidewaysSlack, float damping) { this.body0 = body0; this.body1 = body1; this.hingeAxis = hingeAxis; this.hingePosRel0 = hingePosRel0; this.usingLimit = false; this.damping = damping; // tScalar allowedDistance = 0.005f; this.hingeAxis.Normalize(); Vector3 hingePosRel1 = body0.Position + hingePosRel0 - body1.Position; // generate the two positions relative to each body Vector3 relPos0a = hingePosRel0 + hingeHalfWidth * hingeAxis; Vector3 relPos0b = hingePosRel0 - hingeHalfWidth * hingeAxis; Vector3 relPos1a = hingePosRel1 + hingeHalfWidth * hingeAxis; Vector3 relPos1b = hingePosRel1 - hingeHalfWidth * hingeAxis; float timescale = 1.0f / 20.0f; float allowedDistanceMid = 0.005f; float allowedDistanceSide = sidewaysSlack * hingeHalfWidth; mSidePointConstraints = new ConstraintMaxDistance[2]; mSidePointConstraints[0] = new ConstraintMaxDistance(); mSidePointConstraints[1] = new ConstraintMaxDistance(); mSidePointConstraints[0].Initialise(body0, relPos0a, body1, relPos1a, allowedDistanceSide); mSidePointConstraints[1].Initialise(body0, relPos0b, body1, relPos1b, allowedDistanceSide); mMidPointConstraint = new ConstraintPoint(); mMidPointConstraint.Initialise(body0, hingePosRel0, body1, hingePosRel1, allowedDistanceMid, timescale); if (hingeFwdAngle <= 150) // MAX_HINGE_ANGLE_LIMIT { // choose a direction that is perpendicular to the hinge Vector3 perpDir = Vector3.Up; if (Vector3.Dot(perpDir, hingeAxis) > 0.1f) perpDir = Vector3.Right; // now make it perpendicular to the hinge Vector3 sideAxis = Vector3.Cross(hingeAxis, perpDir); perpDir = Vector3.Cross(sideAxis, hingeAxis); perpDir.Normalize(); // the length of the "arm" TODO take this as a parameter? what's // the effect of changing it? float len = 10.0f * hingeHalfWidth; // Choose a position using that dir. this will be the anchor point // for body 0. relative to hinge Vector3 hingeRelAnchorPos0 = perpDir * len; // anchor point for body 2 is chosen to be in the middle of the // angle range. relative to hinge float angleToMiddle = 0.5f * (hingeFwdAngle - hingeBckAngle); Vector3 hingeRelAnchorPos1 = Vector3.TransformNormal(hingeRelAnchorPos0, Matrix.CreateFromAxisAngle(hingeAxis,MathHelper.ToRadians(-angleToMiddle))); // work out the "string" length float hingeHalfAngle = 0.5f * (hingeFwdAngle + hingeBckAngle); float allowedDistance = len * 2.0f * (float)System.Math.Sin(MathHelper.ToRadians(hingeHalfAngle * 0.5f)); Vector3 hingePos = body1.Position + hingePosRel0; Vector3 relPos0c = hingePos + hingeRelAnchorPos0 - body0.Position; Vector3 relPos1c = hingePos + hingeRelAnchorPos1 - body1.Position; mMaxDistanceConstraint = new ConstraintMaxDistance(); mMaxDistanceConstraint.Initialise(body0, relPos0c, body1, relPos1c, allowedDistance); usingLimit = true; } if (damping <= 0.0f) damping = -1.0f; // just make sure that a value of 0.0 doesn't mess up... else damping = MathHelper.Clamp(damping, 0, 1); }
public void Initialise(Body body0, Body body1, Vector3 hingeAxis, Vector3 hingePosRel0, float hingeHalfWidth, float hingeFwdAngle, float hingeBckAngle, float sidewaysSlack, float damping) { this.body0 = body0; this.body1 = body1; this.hingeAxis = hingeAxis; this.hingePosRel0 = hingePosRel0; usingLimit = false; this.damping = damping; this.hingeAxis.Normalize(); var hingePosRel1 = body0.Position + hingePosRel0 - body1.Position; var relPos0a = hingePosRel0 + hingeHalfWidth * hingeAxis; var relPos0b = hingePosRel0 - hingeHalfWidth * hingeAxis; var relPos1a = hingePosRel1 + hingeHalfWidth * hingeAxis; var relPos1b = hingePosRel1 - hingeHalfWidth * hingeAxis; var timescale = 1.0f / 20.0f; var allowedDistanceMid = 0.005f; var allowedDistanceSide = sidewaysSlack * hingeHalfWidth; mSidePointConstraints = new ConstraintMaxDistance[2]; mSidePointConstraints[0] = new ConstraintMaxDistance(); mSidePointConstraints[1] = new ConstraintMaxDistance(); mSidePointConstraints[0].Initialise(body0, relPos0a, body1, relPos1a, allowedDistanceSide); mSidePointConstraints[1].Initialise(body0, relPos0b, body1, relPos1b, allowedDistanceSide); mMidPointConstraint = new ConstraintPoint(); mMidPointConstraint.Initialise(body0, hingePosRel0, body1, hingePosRel1, allowedDistanceMid, timescale); if (hingeFwdAngle <= 150) { var perpDir = Vector3.Up; if (Vector3.Dot(perpDir, hingeAxis) > 0.1f) { perpDir = Vector3.Right; } var sideAxis = Vector3.Cross(hingeAxis, perpDir); perpDir = Vector3.Cross(sideAxis, hingeAxis); perpDir.Normalize(); var len = 10.0f * hingeHalfWidth; var hingeRelAnchorPos0 = perpDir * len; var angleToMiddle = 0.5f * (hingeFwdAngle - hingeBckAngle); var hingeRelAnchorPos1 = Vector3.TransformNormal(hingeRelAnchorPos0, Matrix.CreateFromAxisAngle(hingeAxis, MathHelper.ToRadians(-angleToMiddle))); var hingeHalfAngle = 0.5f * (hingeFwdAngle + hingeBckAngle); var allowedDistance = len * 2.0f * (float)System.Math.Sin(MathHelper.ToRadians(hingeHalfAngle * 0.5f)); var hingePos = body1.Position + hingePosRel0; var relPos0c = hingePos + hingeRelAnchorPos0 - body0.Position; var relPos1c = hingePos + hingeRelAnchorPos1 - body1.Position; mMaxDistanceConstraint = new ConstraintMaxDistance(); mMaxDistanceConstraint.Initialise(body0, relPos0c, body1, relPos1c, allowedDistance); usingLimit = true; } if (damping <= 0.0f) { damping = -1.0f; } else { damping = MathHelper.Clamp(damping, 0, 1); } }