private void SetMomentOfInertia(InertiaBody body) { if (InertiaBody.NONE == body) { inertia = 0; inertiaInv = 0; return; } Vector3 hitboxSize = Vector3.zero; MeshFilter meshFilter = gameObject.GetComponent <MeshFilter>(); SpriteRenderer renderer = GetComponent <SpriteRenderer>(); if (meshFilter != null) { hitboxSize.x = meshFilter.mesh.bounds.size.x * transform.localScale.x; hitboxSize.y = meshFilter.mesh.bounds.size.y * transform.localScale.y; } else if (renderer != null) { hitboxSize.x = renderer.sprite.bounds.size.x * transform.localScale.x; hitboxSize.y = renderer.sprite.bounds.size.y * transform.localScale.y; } //hitboxSize.z = mesh.bounds.size.z * transform.localScale.z; switch (body) { case InertiaBody.RECTANGLE: { float dx = hitboxSize.x, dy = hitboxSize.y; inertia = 1f / 12f * mass * (dx * dx + dy * dy); break; } case InertiaBody.CIRCLE: { float radius = hitboxSize.x; inertia = .5f * mass * radius * radius; break; } case InertiaBody.ROD: { float length = hitboxSize.x; inertia = 1 / 12f * mass * length * length; break; } case InertiaBody.CIRCULAR_RING: { float outerRadius = hitboxSize.x; float innerRadius = outerRadius * .75f; float t = outerRadius - innerRadius; float r = t / 2; inertia = Mathf.PI * r * r * r * t; break; } case InertiaBody.SQUARE: { float dim = hitboxSize.x; inertia = (1f / 3f) * mass * dim * dim; break; } } inertiaInv = 1 / inertia; }
private void SetMomentOfInertia(InertiaBody body) { inertia = Matrix4x4.identity; inertiaInv = Matrix4x4.identity; if (InertiaBody.NONE == body) { return; } Vector3 hitboxSize = Vector3.zero; MeshFilter meshFilter = gameObject.GetComponent <MeshFilter>(); SpriteRenderer renderer = GetComponent <SpriteRenderer>(); if (meshFilter != null) { hitboxSize.x = meshFilter.mesh.bounds.size.x * transform.localScale.x; hitboxSize.y = meshFilter.mesh.bounds.size.y * transform.localScale.y; hitboxSize.z = meshFilter.mesh.bounds.size.z * transform.localScale.z; } else if (renderer != null) { hitboxSize.x = renderer.sprite.bounds.size.x * transform.localScale.x; hitboxSize.y = renderer.sprite.bounds.size.y * transform.localScale.y; hitboxSize.z = renderer.sprite.bounds.size.z * transform.localScale.z; } //hitboxSize.z = mesh.bounds.size.z * transform.localScale.z; switch (body) { case InertiaBody.BOX: { float oneSixth = 1f / 6f; float side = hitboxSize.x; float numToSet = oneSixth * mass * side * side; inertia.SetRow(0, new Vector4(numToSet, 0, 0, 0)); inertia.SetRow(1, new Vector4(0, numToSet, 0, 0)); inertia.SetRow(2, new Vector4(0, 0, numToSet, 0)); break; } case InertiaBody.CONE: { float radius = hitboxSize.x * .5f; float height = hitboxSize.y; float firstSecond = .6f * mass * height * height + .15f * mass * radius * radius; float third = .3f * mass * radius * radius; inertia.SetRow(0, new Vector4(firstSecond, 0, 0, 0)); inertia.SetRow(1, new Vector4(0, firstSecond, 0, 0)); inertia.SetRow(2, new Vector4(0, 0, third, 0)); break; } case InertiaBody.CUBE: { float oneTwelfth = 1f / 12f; float first = oneTwelfth * mass * (hitboxSize.y * hitboxSize.y + hitboxSize.z * hitboxSize.z); float second = oneTwelfth * mass * (hitboxSize.z * hitboxSize.z + hitboxSize.x * hitboxSize.x); float third = oneTwelfth * mass * (hitboxSize.x * hitboxSize.x + hitboxSize.y * hitboxSize.y); inertia.SetRow(0, new Vector4(first, 0, 0, 0)); inertia.SetRow(1, new Vector4(0, second, 0, 0)); inertia.SetRow(2, new Vector4(0, 0, third, 0)); break; } case InertiaBody.CYLINDER: { float radius = hitboxSize.x * .5f; float height = hitboxSize.y * .5f; float oneTwelfth = 1f / 12f; float firstSecond = oneTwelfth * mass * (3 * radius * radius + height * height); float third = .5f * mass * radius * radius; inertia.SetRow(0, new Vector4(firstSecond, 0, 0, 0)); inertia.SetRow(1, new Vector4(0, firstSecond, 0, 0)); inertia.SetRow(2, new Vector4(0, 0, third, 0)); break; } case InertiaBody.HOLLOW_BOX: { float fiveThirds = 5f / 3f; float first = fiveThirds * mass * (hitboxSize.y * hitboxSize.y + hitboxSize.z * hitboxSize.z); float second = fiveThirds * mass * (hitboxSize.z * hitboxSize.z + hitboxSize.x * hitboxSize.x); float third = fiveThirds * mass * (hitboxSize.x * hitboxSize.x + hitboxSize.y * hitboxSize.y); inertia.SetRow(0, new Vector4(first, 0, 0, 0)); inertia.SetRow(1, new Vector4(0, second, 0, 0)); inertia.SetRow(2, new Vector4(0, 0, third, 0)); break; } case InertiaBody.HOLLOW_CUBE: { float fiveThirdsOverTwo = (5f / 3f) * .5f; float side = hitboxSize.x; float numToSet = fiveThirdsOverTwo * mass * side * side; inertia.SetRow(0, new Vector4(numToSet, 0, 0, 0)); inertia.SetRow(1, new Vector4(0, numToSet, 0, 0)); inertia.SetRow(2, new Vector4(0, 0, numToSet, 0)); break; } case InertiaBody.HOLLOW_SPHERE: { float radius = hitboxSize.x * .5f; // 2/3mr^2 float numToSet = 2f / 3f * mass * radius * radius; inertia.SetRow(0, new Vector4(numToSet, 0, 0, 0)); inertia.SetRow(1, new Vector4(0, numToSet, 0, 0)); inertia.SetRow(2, new Vector4(0, 0, numToSet, 0)); break; } case InertiaBody.SPHERE: { float radius = hitboxSize.x * .5f; // 2/5mr^2 float numToSet = .4f * mass * radius * radius; inertia.SetRow(0, new Vector4(numToSet, 0, 0, 0)); inertia.SetRow(1, new Vector4(0, numToSet, 0, 0)); inertia.SetRow(2, new Vector4(0, 0, numToSet, 0)); break; } default: { break; } } inertiaInv.SetRow(0, inertia.GetColumn(0)); inertiaInv.SetRow(1, inertia.GetColumn(1)); inertiaInv.SetRow(2, inertia.GetColumn(2)); inertiaInv.SetRow(3, inertia.GetColumn(3)); }