A WheelInfo class from a Bullet physics port, representing a single wheel's configuration and runtime state. It stores chassis connection, direction/axle, suspension and friction parameters, runtime raycast info and methods to initialize from a construction info struct and update per-frame suspension/contact state.
/* * C# / XNA port of Bullet (c) 2011 Mark Neale <[email protected]> * * Bullet Continuous Collision Detection and Physics Library * Copyright (c) 2003-2008 Erwin Coumans http://www.bulletphysics.com/ * * This software is provided 'as-is', without any express or implied warranty. * In no event will the authors be held liable for any damages arising from * the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ // Adapted from BulletXNA 73b2e1b9: namespace isolation, no XNA rendering, one type per file. #nullable disable #pragma warning disable CS1591, CS0168, CS0219, CS0414, CS0660, CS0661, CS0659, CS0693, CS8981, CS0108, CS0114 using System; using HumanoidRetargeter.Core.Formats.Mmd.Bullet.LinearMath; namespace HumanoidRetargeter.Core.Formats.Mmd.Bullet.BulletDynamics; internal class WheelInfo { public WheelRaycastInfo m_raycastInfo; public IndexedMatrix m_worldTransform; public IndexedVector3 m_chassisConnectionPointCS; //const public IndexedVector3 m_wheelDirectionCS; //const public IndexedVector3 m_wheelAxleCS; // const or modified by steering public float m_suspensionRestLength1; //const public float m_maxSuspensionTravelCm; public float GetSuspensionRestLength() { return m_suspensionRestLength1; } public float m_wheelsRadius; //const public float m_suspensionStiffness; //const public float m_wheelsDampingCompression; //const public float m_wheelsDampingRelaxation; //const public float m_frictionSlip; public float m_steering; public float m_rotation; public float m_deltaRotation; public float m_rollInfluence; public float m_maxSuspensionForce; public float m_engineForce; public float m_brake; public bool m_bIsFrontWheel; public Object m_clientInfo; //can be used to store pointer to sync transforms... public WheelInfo(ref WheelInfoConstructionInfo ci) { m_suspensionRestLength1 = ci.m_suspensionRestLength; m_maxSuspensionTravelCm = ci.m_maxSuspensionTravelCm; m_wheelsRadius = ci.m_wheelRadius; m_suspensionStiffness = ci.m_suspensionStiffness; m_wheelsDampingCompression = ci.m_wheelsDampingCompression; m_wheelsDampingRelaxation = ci.m_wheelsDampingRelaxation; m_chassisConnectionPointCS = ci.m_chassisConnectionCS; m_wheelDirectionCS = ci.m_wheelDirectionCS; m_wheelAxleCS = ci.m_wheelAxleCS; m_frictionSlip = ci.m_frictionSlip; m_steering = 0f; m_engineForce = 0f; m_rotation = 0f; m_deltaRotation = 0f; m_brake = 0f; m_rollInfluence = .1f; m_bIsFrontWheel = ci.m_bIsFrontWheel; m_maxSuspensionForce = ci.m_maxSuspensionForce; } public void UpdateWheel(RigidBody chassis, ref WheelRaycastInfo raycastInfo) { if (m_raycastInfo.m_isInContact) { float project = IndexedVector3.Dot(m_raycastInfo.m_contactNormalWS, m_raycastInfo.m_wheelDirectionWS); IndexedVector3 chassis_velocity_at_contactPoint; IndexedVector3 relpos = m_raycastInfo.m_contactPointWS - chassis.GetCenterOfMassPosition(); chassis_velocity_at_contactPoint = chassis.GetVelocityInLocalPoint(ref relpos); float projVel = IndexedVector3.Dot(m_raycastInfo.m_contactNormalWS, chassis_velocity_at_contactPoint); if (project >= -0.1f) { m_suspensionRelativeVelocity = 0f; m_clippedInvContactDotSuspension = 1.0f / 0.1f; } else { float inv = -1f / project; m_suspensionRelativeVelocity = projVel * inv; m_clippedInvContactDotSuspension = inv; } } else // Not in contact : position wheel in a nice (rest length) position { m_raycastInfo.m_suspensionLength = this.GetSuspensionRestLength(); m_suspensionRelativeVelocity = 0f; m_raycastInfo.m_contactNormalWS = -m_raycastInfo.m_wheelDirectionWS; m_clippedInvContactDotSuspension = 1f; } } public float m_clippedInvContactDotSuspension; public float m_suspensionRelativeVelocity; //calculated by suspension public float m_wheelsSuspensionForce; public float m_skidInfo; }