private static void UpdateWindingAngleDelta(WindingData winding) { var sin = winding.CurrentDummyWorld.Right.Dot(winding.LastDummyWorld.Up); var cos = winding.CurrentDummyWorld.Right.Dot(winding.LastDummyWorld.Right); // Circumference is C=2πr for whole circle (2π) but I'm only interested in part of it (atan(y,x)*π). winding.AngleDelta = (float)Math.Atan2(sin, cos); }
private static Vector3 ComputeTorqueFromRopeImpulse(WindingData windingData, InternalRopeData ropeData, Vector3 ropeDirectionVector, Vector3 centerDelta) { /* * /R = rope direction vector (unit length, world space) * /A = drum axis (unit length, world space) * /r = displacement vector for torque application (world space) from center of mass * /tau = torque applied * /C_d = center delta (center of winding (world space) - center of mass (world space)) * /F = force * r = drum radius * I = impulse applied * * /r = |/R x /A| * r + C_d * /F = /R * -I * /tau = /r x /F */ Vector3 A, r, F, tau; Vector3.Normalize(ref ropeDirectionVector, out ropeDirectionVector); A = windingData.CurrentDummyWorld.Backward; Vector3.Cross(ref ropeDirectionVector, ref A, out r); r = r * windingData.Radius + centerDelta; F = ropeDirectionVector * ropeData.ImpulseApplied; Vector3.Cross(ref r, ref F, out tau); return tau; }
private static void DeactivateWinding(long hookEntityId, WindingData winding = null) { if (winding == null) { m_hookIdToActiveWinding.TryGetValue(hookEntityId, out winding); } if (winding != null && winding.Emitter != null) { winding.Emitter.StopSound(false); winding.Emitter = null; winding.Sound = null; } m_hookIdToActiveWinding.Remove(hookEntityId); }
private static void UpdateDummyWorld(MyPositionComponentBase windingEntityPositionComponent, WindingData winding) { winding.LastDummyWorld = winding.CurrentDummyWorld; winding.CurrentDummyWorld = MatrixD.Multiply(winding.LocalDummy, windingEntityPositionComponent.WorldMatrix); }
private static void ActivateWinding(long hookEntityId, WindingData winding, MyRopeDefinition attachedRope) { Debug.Assert(winding != null); Debug.Assert(!m_hookIdToActiveWinding.ContainsKey(hookEntityId), "Winding already added"); Debug.Assert(m_hookIdToRopeId.ContainsKey(hookEntityId)); m_hookIdToActiveWinding[hookEntityId] = winding; var hookEntity = MyEntities.GetEntityById(hookEntityId); UpdateDummyWorld(hookEntity.PositionComp, winding); if (attachedRope.WindingSound != null) { winding.Sound = attachedRope.WindingSound; winding.Emitter = new MyEntity3DSoundEmitter(hookEntity); } }