public static void DebugDrawConstraint(TypedConstraint constraint, IDebugDraw debugDraw) { bool drawFrames = (debugDraw.GetDebugMode() & DebugDrawModes.DBG_DrawConstraints) != 0; bool drawLimits = (debugDraw.GetDebugMode() & DebugDrawModes.DBG_DrawConstraintLimits) != 0; float dbgDrawSize = constraint.GetDbgDrawSize(); if (dbgDrawSize <= 0f) { return; } switch (constraint.GetConstraintType()) { case TypedConstraintType.POINT2POINT_CONSTRAINT_TYPE: { Point2PointConstraint p2pC = constraint as Point2PointConstraint; IndexedMatrix tr = IndexedMatrix.Identity; IndexedVector3 pivot = p2pC.GetPivotInA(); pivot = p2pC.GetRigidBodyA().GetCenterOfMassTransform() * pivot; tr._origin = pivot; debugDraw.DrawTransform(ref tr, dbgDrawSize); // that ideally should draw the same frame pivot = p2pC.GetPivotInB(); pivot = p2pC.GetRigidBodyB().GetCenterOfMassTransform() * pivot; tr._origin = pivot; if (drawFrames) { debugDraw.DrawTransform(ref tr, dbgDrawSize); } } break; case TypedConstraintType.HINGE_CONSTRAINT_TYPE: { HingeConstraint pHinge = constraint as HingeConstraint; IndexedMatrix tr = pHinge.GetRigidBodyA().GetCenterOfMassTransform() * pHinge.GetAFrame(); if (drawFrames) { debugDraw.DrawTransform(ref tr, dbgDrawSize); } tr = pHinge.GetRigidBodyB().GetCenterOfMassTransform() * pHinge.GetBFrame(); if (drawFrames) { debugDraw.DrawTransform(ref tr, dbgDrawSize); } float minAng = pHinge.GetLowerLimit(); float maxAng = pHinge.GetUpperLimit(); if (minAng == maxAng) { break; } bool drawSect = true; if (minAng > maxAng) { minAng = 0f; maxAng = MathUtil.SIMD_2_PI; drawSect = false; } if (drawLimits) { IndexedVector3 center = tr._origin; IndexedVector3 normal = tr._basis.GetColumn(2); IndexedVector3 axis = tr._basis.GetColumn(0); IndexedVector3 zero = IndexedVector3.Zero; debugDraw.DrawArc(ref center, ref normal, ref axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, ref zero, drawSect); } } break; case TypedConstraintType.CONETWIST_CONSTRAINT_TYPE: { ConeTwistConstraint pCT = constraint as ConeTwistConstraint; IndexedMatrix tr = pCT.GetRigidBodyA().GetCenterOfMassTransform() * pCT.GetAFrame(); if (drawFrames) { debugDraw.DrawTransform(ref tr, dbgDrawSize); } tr = pCT.GetRigidBodyB().GetCenterOfMassTransform() * pCT.GetBFrame(); if (drawFrames) { debugDraw.DrawTransform(ref tr, dbgDrawSize); } IndexedVector3 zero = IndexedVector3.Zero; if (drawLimits) { //const float length = float(5); float length = dbgDrawSize; const int nSegments = 8 * 4; float fAngleInRadians = MathUtil.SIMD_2_PI * (float)(nSegments - 1) / (float)nSegments; IndexedVector3 pPrev = pCT.GetPointForAngle(fAngleInRadians, length); pPrev = tr * pPrev; for (int i = 0; i < nSegments; i++) { fAngleInRadians = MathUtil.SIMD_2_PI * (float)i / (float)nSegments; IndexedVector3 pCur = pCT.GetPointForAngle(fAngleInRadians, length); pCur = tr * pCur; debugDraw.DrawLine(ref pPrev, ref pCur, ref zero); if (i % (nSegments / 8) == 0) { IndexedVector3 origin = tr._origin; debugDraw.DrawLine(ref origin, ref pCur, ref zero); } pPrev = pCur; } float tws = pCT.GetTwistSpan(); float twa = pCT.GetTwistAngle(); bool useFrameB = (pCT.GetRigidBodyB().GetInvMass() > 0f); if (useFrameB) { tr = pCT.GetRigidBodyB().GetCenterOfMassTransform() * pCT.GetBFrame(); } else { tr = pCT.GetRigidBodyA().GetCenterOfMassTransform() * pCT.GetAFrame(); } IndexedVector3 pivot = tr._origin; IndexedVector3 normal = tr._basis.GetColumn(0); IndexedVector3 axis = tr._basis.GetColumn(1); debugDraw.DrawArc(ref pivot, ref normal, ref axis, dbgDrawSize, dbgDrawSize, -twa - tws, -twa + tws, ref zero, true); } } break; case TypedConstraintType.D6_CONSTRAINT_TYPE: case TypedConstraintType.D6_SPRING_CONSTRAINT_TYPE: { Generic6DofConstraint p6DOF = constraint as Generic6DofConstraint; IndexedMatrix tr = p6DOF.GetCalculatedTransformA(); if (drawFrames) { debugDraw.DrawTransform(ref tr, dbgDrawSize); } tr = p6DOF.GetCalculatedTransformB(); if (drawFrames) { debugDraw.DrawTransform(ref tr, dbgDrawSize); } IndexedVector3 zero = IndexedVector3.Zero; if (drawLimits) { tr = p6DOF.GetCalculatedTransformA(); IndexedVector3 center = p6DOF.GetCalculatedTransformB()._origin; // up is axis 1 not 2 ? IndexedVector3 up = tr._basis.GetColumn(1); IndexedVector3 axis = tr._basis.GetColumn(0); float minTh = p6DOF.GetRotationalLimitMotor(1).m_loLimit; float maxTh = p6DOF.GetRotationalLimitMotor(1).m_hiLimit; float minPs = p6DOF.GetRotationalLimitMotor(2).m_loLimit; float maxPs = p6DOF.GetRotationalLimitMotor(2).m_hiLimit; debugDraw.DrawSpherePatch(ref center, ref up, ref axis, dbgDrawSize * .9f, minTh, maxTh, minPs, maxPs, ref zero); axis = tr._basis.GetColumn(1); float ay = p6DOF.GetAngle(1); float az = p6DOF.GetAngle(2); float cy = (float)Math.Cos(ay); float sy = (float)Math.Sin(ay); float cz = (float)Math.Cos(az); float sz = (float)Math.Sin(az); IndexedVector3 ref1 = new IndexedVector3( cy * cz * axis.X + cy * sz * axis.Y - sy * axis.Z, -sz * axis.X + cz * axis.Y, cz * sy * axis.X + sz * sy * axis.Y + cy * axis.Z); tr = p6DOF.GetCalculatedTransformB(); IndexedVector3 normal = -tr._basis.GetColumn(0); float minFi = p6DOF.GetRotationalLimitMotor(0).m_loLimit; float maxFi = p6DOF.GetRotationalLimitMotor(0).m_hiLimit; if (minFi > maxFi) { debugDraw.DrawArc(ref center, ref normal, ref ref1, dbgDrawSize, dbgDrawSize, -MathUtil.SIMD_PI, MathUtil.SIMD_PI, ref zero, false); } else if (minFi < maxFi) { debugDraw.DrawArc(ref center, ref normal, ref ref1, dbgDrawSize, dbgDrawSize, minFi, maxFi, ref zero, false); } tr = p6DOF.GetCalculatedTransformA(); IndexedVector3 bbMin = p6DOF.GetTranslationalLimitMotor().m_lowerLimit; IndexedVector3 bbMax = p6DOF.GetTranslationalLimitMotor().m_upperLimit; debugDraw.DrawBox(ref bbMin, ref bbMax, ref tr, ref zero); } } break; case TypedConstraintType.SLIDER_CONSTRAINT_TYPE: { SliderConstraint pSlider = constraint as SliderConstraint; IndexedMatrix tr = pSlider.GetCalculatedTransformA(); if (drawFrames) { debugDraw.DrawTransform(ref tr, dbgDrawSize); } tr = pSlider.GetCalculatedTransformB(); if (drawFrames) { debugDraw.DrawTransform(ref tr, dbgDrawSize); } IndexedVector3 zero = IndexedVector3.Zero; if (drawLimits) { IndexedMatrix tr2 = pSlider.GetCalculatedTransformA(); IndexedVector3 li_min = tr2 * new IndexedVector3(pSlider.GetLowerLinLimit(), 0f, 0f); IndexedVector3 li_max = tr2 * new IndexedVector3(pSlider.GetUpperLinLimit(), 0f, 0f); debugDraw.DrawLine(ref li_min, ref li_max, ref zero); IndexedVector3 normal = tr._basis.GetColumn(0); IndexedVector3 axis = tr._basis.GetColumn(1); float a_min = pSlider.GetLowerAngLimit(); float a_max = pSlider.GetUpperAngLimit(); IndexedVector3 center = pSlider.GetCalculatedTransformB()._origin; debugDraw.DrawArc(ref center, ref normal, ref axis, dbgDrawSize, dbgDrawSize, a_min, a_max, ref zero, true); } } break; default: break; } return; }
//---------------------------------------------------------------------------------------------------------------- public override void InitializeDemo() { CollisionShape groundShape = new BoxShape(new IndexedVector3(50, 0.1f, 50)); IndexedVector3 wheelDimensions = new IndexedVector3(wheelWidth, wheelRadius, wheelRadius); m_wheelShape = new CylinderShapeX(ref wheelDimensions); m_collisionShapes.Add(groundShape); m_collisionConfiguration = new DefaultCollisionConfiguration(); m_dispatcher = new CollisionDispatcher(m_collisionConfiguration); IndexedVector3 worldMin = new IndexedVector3(-1000, -1000, -1000); IndexedVector3 worldMax = new IndexedVector3(1000, 1000, 1000); m_broadphase = new AxisSweep3Internal(ref worldMin, ref worldMax, 0xfffe, 0xffff, 16384, null, false); m_constraintSolver = new SequentialImpulseConstraintSolver(); m_dynamicsWorld = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_constraintSolver, m_collisionConfiguration); IndexedMatrix tr = IndexedMatrix.CreateTranslation(0, -10, 0); LocalCreateRigidBody(0f, ref tr, groundShape); #if true CollisionShape chassisShape = new BoxShape(new IndexedVector3(1.0f, 0.5f, 2.0f)); //CollisionShape chassisShape = new BoxShape(new IndexedVector3(1.0f, 0.5f, 1.0f)); m_collisionShapes.Add(chassisShape); CompoundShape compound = new CompoundShape(); m_collisionShapes.Add(compound); //localTrans effectively shifts the center of mass with respect to the chassis IndexedMatrix localTrans = IndexedMatrix.CreateTranslation(0, 1, 0); compound.AddChildShape(ref localTrans, chassisShape); { CollisionShape suppShape = new BoxShape(new IndexedVector3(0.5f, 0.1f, 0.5f)); //localTrans effectively shifts the center of mass with respect to the chassis IndexedMatrix suppLocalTrans = IndexedMatrix.CreateTranslation(0f, 1.0f, 2.5f); compound.AddChildShape(ref suppLocalTrans, suppShape); } tr._origin = IndexedVector3.Zero; m_carChassis = LocalCreateRigidBody(800f, ref tr, compound);//chassisShape); #endif { #if true CollisionShape liftShape = new BoxShape(new IndexedVector3(0.5f, 2.0f, 0.05f)); m_collisionShapes.Add(liftShape); m_liftStartPos = new IndexedVector3(0.0f, 2.5f, 3.05f); IndexedMatrix liftTrans = IndexedMatrix.CreateTranslation(m_liftStartPos); m_liftBody = LocalCreateRigidBody(10f, ref liftTrans, liftShape); IndexedMatrix localA = MathUtil.SetEulerZYX(0f, MathUtil.SIMD_HALF_PI, 0f); localA._origin = new IndexedVector3(0f, 1.0f, 3.05f); IndexedMatrix localB = MathUtil.SetEulerZYX(0f, MathUtil.SIMD_HALF_PI, 0f); localB._origin = new IndexedVector3(0f, -1.5f, -0.05f); m_liftHinge = new HingeConstraint(m_carChassis, m_liftBody, ref localA, ref localB); MathUtil.PrintMatrix(BulletGlobals.g_streamWriter, "hinge aFrame", m_liftHinge.GetAFrame()); MathUtil.PrintMatrix(BulletGlobals.g_streamWriter, "hinge bFrame", m_liftHinge.GetBFrame()); m_liftHinge.SetLimit(0.0f, 0.0f); m_dynamicsWorld.AddConstraint(m_liftHinge, true); CollisionShape forkShapeA = new BoxShape(new IndexedVector3(1.0f, 0.1f, 0.1f)); m_collisionShapes.Add(forkShapeA); CompoundShape forkCompound = new CompoundShape(); m_collisionShapes.Add(forkCompound); IndexedMatrix forkLocalTrans = IndexedMatrix.Identity; forkCompound.AddChildShape(ref forkLocalTrans, forkShapeA); CollisionShape forkShapeB = new BoxShape(new IndexedVector3(0.1f, 0.02f, 0.6f)); m_collisionShapes.Add(forkShapeB); forkLocalTrans = IndexedMatrix.CreateTranslation(-0.9f, -0.08f, 0.7f); forkCompound.AddChildShape(ref forkLocalTrans, forkShapeB); CollisionShape forkShapeC = new BoxShape(new IndexedVector3(0.1f, 0.02f, 0.6f)); m_collisionShapes.Add(forkShapeC); forkLocalTrans = IndexedMatrix.CreateTranslation(0.9f, -0.08f, 0.7f); forkCompound.AddChildShape(ref forkLocalTrans, forkShapeC); m_forkStartPos = new IndexedVector3(0.0f, 0.6f, 3.2f); IndexedMatrix forkTrans = IndexedMatrix.CreateTranslation(m_forkStartPos); m_forkBody = LocalCreateRigidBody(5f, ref forkTrans, forkCompound); localA = IndexedMatrix.Identity; localB = IndexedMatrix.Identity; localA._basis.SetEulerZYX(0, 0, MathUtil.SIMD_HALF_PI); localA._origin = new IndexedVector3(0.0f, -1.9f, 0.05f); localB._basis.SetEulerZYX(0, 0, MathUtil.SIMD_HALF_PI); localB._origin = new IndexedVector3(0.0f, 0.0f, -0.1f); m_forkSlider = new SliderConstraint(m_liftBody, m_forkBody, ref localA, ref localB, true); m_forkSlider.SetLowerLinLimit(0.1f); m_forkSlider.SetUpperLinLimit(0.1f); // m_forkSlider.setLowerAngLimit(-LIFT_EPS); // m_forkSlider.setUpperAngLimit(LIFT_EPS); m_forkSlider.SetLowerAngLimit(0.0f); m_forkSlider.SetUpperAngLimit(0.0f); m_dynamicsWorld.AddConstraint(m_forkSlider, true); #endif #if true CompoundShape loadCompound = new CompoundShape(false); m_collisionShapes.Add(loadCompound); CollisionShape loadShapeA = new BoxShape(new IndexedVector3(2.0f, 0.5f, 0.5f)); m_collisionShapes.Add(loadShapeA); IndexedMatrix loadTrans = IndexedMatrix.Identity; loadCompound.AddChildShape(ref loadTrans, loadShapeA); CollisionShape loadShapeB = new BoxShape(new IndexedVector3(0.1f, 1.0f, 1.0f)); m_collisionShapes.Add(loadShapeB); loadTrans = IndexedMatrix.CreateTranslation(2.1f, 0.0f, 0.0f); loadCompound.AddChildShape(ref loadTrans, loadShapeB); CollisionShape loadShapeC = new BoxShape(new IndexedVector3(0.1f, 1.0f, 1.0f)); m_collisionShapes.Add(loadShapeC); loadTrans = IndexedMatrix.CreateTranslation(-2.1f, 0.0f, 0.0f); loadCompound.AddChildShape(ref loadTrans, loadShapeC); m_loadStartPos = new IndexedVector3(0.0f, -3.5f, 7.0f); loadTrans = IndexedMatrix.CreateTranslation(m_loadStartPos); m_loadBody = LocalCreateRigidBody(4f, ref loadTrans, loadCompound); #endif } //m_carChassis.setDamping(0.2f, 0.2f); ClientResetScene(); /// create vehicle { m_vehicleRayCaster = new DefaultVehicleRaycaster(m_dynamicsWorld); m_vehicle = new RaycastVehicle(m_tuning, m_carChassis, m_vehicleRayCaster); ///never deactivate the vehicle m_carChassis.SetActivationState(ActivationState.DISABLE_DEACTIVATION); m_dynamicsWorld.AddVehicle(m_vehicle); float connectionHeight = 1.2f; bool isFrontWheel = true; //choose coordinate system m_vehicle.SetCoordinateSystem(rightIndex, upIndex, forwardIndex); IndexedVector3 connectionPointCS0 = IndexedVector3.Zero; //connectionPointCS0 = new IndexedVector3(CUBE_HALF_EXTENTS, connectionHeight, CUBE_HALF_EXTENTS); //m_vehicle.addWheel(ref connectionPointCS0, ref wheelDirectionCS0, ref wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); connectionPointCS0 = new IndexedVector3(CUBE_HALF_EXTENTS - (0.3f * wheelWidth), connectionHeight, 2.0f * CUBE_HALF_EXTENTS - wheelRadius); m_vehicle.AddWheel(ref connectionPointCS0, ref wheelDirectionCS0, ref wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); connectionPointCS0 = new IndexedVector3(-CUBE_HALF_EXTENTS + (0.3f * wheelWidth), connectionHeight, 2.0f * CUBE_HALF_EXTENTS - wheelRadius); m_vehicle.AddWheel(ref connectionPointCS0, ref wheelDirectionCS0, ref wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); //isFrontWheel = false; connectionPointCS0 = new IndexedVector3(-CUBE_HALF_EXTENTS + (0.3f * wheelWidth), connectionHeight, -2.0f * CUBE_HALF_EXTENTS + wheelRadius); m_vehicle.AddWheel(ref connectionPointCS0, ref wheelDirectionCS0, ref wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); connectionPointCS0 = new IndexedVector3(CUBE_HALF_EXTENTS - (0.3f * wheelWidth), connectionHeight, -2.0f * CUBE_HALF_EXTENTS + wheelRadius); m_vehicle.AddWheel(ref connectionPointCS0, ref wheelDirectionCS0, ref wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); for (int i = 0; i < m_vehicle.GetNumWheels(); i++) { WheelInfo wheel = m_vehicle.GetWheelInfo(i); wheel.m_suspensionStiffness = suspensionStiffness; wheel.m_wheelsDampingRelaxation = suspensionDamping; wheel.m_wheelsDampingCompression = suspensionCompression; wheel.m_frictionSlip = wheelFriction; wheel.m_rollInfluence = rollInfluence; } } SetCameraDistance(36.0f); SetTexturing(true); SetShadows(true); }