protected override void SimpleInit() { if (!ObjectPrivate.TryGetFirstComponent(out RigidBody)) { Log.Write(LogLevel.Error, __SimpleTag, "Simple Mover requires a Rigidbody set to motion type Keyframed"); return; } if (RigidBody.GetMotionType() != RigidBodyMotionType.MotionTypeKeyframed) { Log.Write(LogLevel.Error, __SimpleTag, "Simple Mover requires a Rigidbody set to motion type Keyframed"); return; } thisObjectData = new SimpleData(this); thisObjectData.SourceObjectId = ObjectPrivate.ObjectId; thisObjectData.AgentInfo = null; thisObjectData.ObjectId = ObjectPrivate.ObjectId; RigidBody.SetCenterOfMass(RotationPivot); Subscribe(null); Quaternion rotation = Quaternion.FromEulerAngles(Mathf.RadiansPerDegree * RotationOffset); returnRotation = ObjectPrivate.InitialRotation; movedRotation = returnRotation * rotation; numTurns = (int)((RotationOffset.Length() + 179.0f) / 360f); bool noRotation = RotationOffset.Length() < 0.5f; if (noRotation) { worldRotationAxis = Vector.Up; } else { float rotationAngle; rotation.ToAngleAxis(out rotationAngle, out localRotationAxis); if (Math.Abs(rotationAngle % TwoPI) < 0.001f) { // rotation axis won't be calculated correctly for exact multiple of 360 rotation // adjust euler angles slightly and re-calculate float x = RotationOffset.X; float y = RotationOffset.Y; float z = RotationOffset.Z; if (x != 0) { x = Math.Sign(x) * (Math.Abs(x) - 1.0f); } if (y != 0) { y = Math.Sign(y) * (Math.Abs(y) - 1.0f); } if (z != 0) { z = Math.Sign(z) * (Math.Abs(z) - 1.0f); } Vector adjustedOffset = new Vector(x, y, z); Quaternion adjustedRotation = Quaternion.FromEulerAngles(Mathf.RadiansPerDegree * adjustedOffset); float tempAngle; adjustedRotation.ToAngleAxis(out tempAngle, out localRotationAxis); } worldRotationAxis = localRotationAxis.Rotate(ref returnRotation); } float moveAngle = GetAngleFromZero(movedRotation); rotateSpeed = Math.Abs(moveAngle + numTurns * TwoPI) / (MoveDuration * SpeedCurveAverage()); if (!noRotation) { Quaternion unitRotation = Quaternion.FromAngleAxis(1f, localRotationAxis); turnDirection = Math.Sign(GetAngleFromZero(returnRotation * unitRotation)); } returnPosition = ObjectPrivate.InitialPosition + RotationPivot.Rotate(ref returnRotation); movedPosition = returnPosition + (PositionOffset).Rotate(ref returnRotation); translateSpeed = (movedPosition - returnPosition).Length() / (MoveDuration * SpeedCurveAverage()); if (StartMoved) { RigidBody.SetOrientation(movedRotation, (e) => { SetPositionOfCOM(movedPosition); }); turnCount = numTurns; state = State.Moved; } else { SetPositionOfCOM(returnPosition); state = State.Returned; } if (__SimpleDebugging) { Log.Write("rotation angle:" + moveAngle + " around:" + localRotationAxis + " world space axis:" + worldRotationAxis + " revolutions:" + numTurns); } }