float GradientWRTShell(TelescopeShell shell, Vector3 targetPos) { // Changing the twist angle causes the end effector to move // along the tangent of the circle centered on the shell base. // First, compute the center of the circle. Vector3 shellBase = shell.StartPointWS; Vector3 circleNormal = shell.StartTangentWS.normalized; Vector3 currentEndEff = segment.LastShell.EndPointWS; // The circle normal remains the same, but is shifted so that // the current end effector is in the plane. Vector3 fromEnd = shellBase - currentEndEff; Vector3 nonPlanar = Vector3.Dot(fromEnd, circleNormal) * circleNormal; Vector3 circleCenter = currentEndEff + (fromEnd - nonPlanar); // The gradient is then the cross product of the current end position // and the desired end position. This gives the axis of rotation // required to move it there. Vector3 centerToCurrent = currentEndEff - circleCenter; Vector3 currentToTarget = targetPos - currentEndEff; Vector3 axis = Vector3.Cross(centerToCurrent, currentToTarget); // We can only rotate about the fixed shell axis, however, // so the dot product gives the contribution from this axis. return(Vector3.Dot(circleNormal, axis)); }
void AddGradientToTelescope(List <float> angles) { // Apply first telescope separately float firstAngle = angles[0]; if (FreezeFirst) { firstAngle = 0; } // Since the first telescope is free, we just apply rotation about the tangent Vector3 firstTangent = segment.shells[0].transform.forward; Quaternion firstRotation = Quaternion.AngleAxis(firstAngle, firstTangent); segment.shells[0].transform.rotation = firstRotation * segment.shells[0].transform.rotation; // For the rest, just add to the twist angle for (int i = 1; i < angles.Count; i++) { TelescopeShell s = segment.shells[i]; s.twistAngle = Mathf.Repeat(s.twistAngle - angles[i], 360); if (s.twistAngle > 180) { s.twistAngle -= 360; } } }
// Update is called once per frame void LateUpdate() { if (Input.GetKeyDown("i")) { meshRenderer.enabled = true; segment = FindObjectOfType <TelescopeSegment>(); if (segment) { TelescopeShell shell = segment.LastShell; transform.parent = shell.transform; segment.MinExt = 0.35f; segment.ExtendImmediate(0); } } if (Input.GetKeyDown("2")) { SplineCanvas c = FindObjectOfType <SplineCanvas>(); c.ReloadFromFile("rescue.canvas"); } if (Input.GetKeyDown("1")) { animator.SetTrigger("toggle-close"); if (!rescued) { rescued = true; teddyBear.transform.parent = transform; } else { teddyBear.transform.parent = null; teddyBear.activate = true; CameraControl cc = Camera.main.GetComponent <CameraControl>(); cc.FreeMove(); } } }