/// <summary> /// Computes the inertia tensor of a rigid body using box inertia definition /// </summary> public static void ComputeIntertiaTensor(MyRigidBody rbo) { MyCommonDebugUtils.AssertDebug(rbo != null); MyCommonDebugUtils.AssertDebug(rbo.GetRBElementList().Count > 0); MyCommonDebugUtils.AssertDebug(rbo.GetMass() > 0); float mass = rbo.GetMass(); BoundingBox box; box.Min = new Vector3(FLT_MAX); box.Max = new Vector3(FLT_MIN); BoundingBox aabb; Matrix infTensor = new Matrix(); infTensor.M11 = FLT_MAX; infTensor.M22 = FLT_MAX; infTensor.M33 = FLT_MAX; infTensor.M44 = 1.0f; if (rbo.IsStatic()) { rbo.InertiaTensor = infTensor; return; } if (rbo.GetRBElementList().Count > 1) { for (int e = 0; e < rbo.GetRBElementList().Count; e++) { MyRBElement el = rbo.GetRBElementList()[e]; switch (el.GetElementType()) { case MyRBElementType.ET_TRIANGLEMESH: { rbo.InertiaTensor = infTensor; return; } break; case MyRBElementType.ET_VOXEL: { rbo.InertiaTensor = infTensor; return; } break; default: { aabb = el.GetWorldSpaceAABB(); box = BoundingBox.CreateMerged(box, aabb); } break; } } Vector3 size = box.Max - box.Min; infTensor.M11 = mass * (size.Y * size.Y + size.Z * size.Z) / 12.0f; infTensor.M22 = mass * (size.X * size.X + size.Z * size.Z) / 12.0f; infTensor.M33 = mass * (size.X * size.X + size.Y * size.Y) / 12.0f; infTensor.M44 = 1.0f; rbo.InertiaTensor = infTensor; rbo.InvertInertiaTensor = Matrix.Invert(infTensor); return; } MyRBElement elem = rbo.GetRBElementList()[0]; switch (elem.GetElementType()) { case MyRBElementType.ET_TRIANGLEMESH: { rbo.InertiaTensor = infTensor; infTensor.M11 = 0.0f; infTensor.M22 = 0.0f; infTensor.M33 = 0.0f; infTensor.M44 = 0.0f; rbo.InvertInertiaTensor = infTensor; return; } break; case MyRBElementType.ET_VOXEL: { rbo.InertiaTensor = infTensor; infTensor.M11 = 0.0f; infTensor.M22 = 0.0f; infTensor.M33 = 0.0f; infTensor.M44 = 0.0f; rbo.InvertInertiaTensor = infTensor; return; } case MyRBElementType.ET_SPHERE: { float radius = ((MyRBSphereElement)elem).Radius; infTensor.M11 = 2.0f / 5.0f * mass * radius * radius; infTensor.M22 = 2.0f / 5.0f * mass * radius * radius; infTensor.M33 = 2.0f / 5.0f * mass * radius * radius; infTensor.M44 = 1.0f; rbo.InertiaTensor = infTensor; //rbo.InvertInertiaTensor = Matrix.Invert(infTensor); return; } break; case MyRBElementType.ET_BOX: { //Vector3 size = ((MyRBBoxElement)elem).Size; //infTensor.M11 = mass * (size.Y * size.Y + size.Z * size.Z) / 12.0f; //infTensor.M22 = mass * (size.X * size.X + size.Z * size.Z) / 12.0f; //infTensor.M33 = mass * (size.X * size.X + size.Y * size.Y) / 12.0f; //infTensor.M44 = 1.0f; //rbo.InertiaTensor = infTensor; //rbo.InvertInertiaTensor = Matrix.Invert(infTensor); // HACK: After speaking with PetrM, computing changed like box is sphere float radius = ((MyRBBoxElement)elem).Size.Length() / 2; infTensor.M11 = 2.0f / 5.0f * mass * radius * radius; infTensor.M22 = 2.0f / 5.0f * mass * radius * radius; infTensor.M33 = 2.0f / 5.0f * mass * radius * radius; infTensor.M44 = 1.0f; rbo.InertiaTensor = infTensor; //rbo.InvertInertiaTensor = Matrix.Invert(infTensor); return; } break; default: MyCommonDebugUtils.AssertDebug(false); break; } }