TelescopeSegment CreateStraightSegment(float length, float radius)
        {
            GameObject       segObj = new GameObject();
            TelescopeSegment seg    = segObj.AddComponent <TelescopeSegment>();

            List <TelescopeParameters> paramList = new List <TelescopeParameters>();
            float thickness   = Constants.WALL_THICKNESS;
            float startRadius = radius + 3 * thickness + 3 * length * Constants.TAPER_SLOPE;

            TelescopeParameters firstParam = new TelescopeParameters(length,
                                                                     startRadius, thickness, 0, 0, 0);

            paramList.Add(firstParam);

            paramList.Add(new TelescopeParameters(0, 0, 0, 0, 0, 0));
            paramList.Add(new TelescopeParameters(0, 0, 0, 0, 0, 0));

            seg.material = segment1.material;
            seg.MakeShellsFromDiffs(paramList);
            seg.transform.parent = transform;

            return(seg);
        }
Beispiel #2
0
        public static TelescopeSegment telescopeOfCone(Vector3 startPos, float startRadius,
                                                       Vector3 endPos, float endRadius, Vector3 curvatureCenter,
                                                       float wallThickness = Constants.WALL_THICKNESS,
                                                       bool useCurvature   = false)
        {
            float   curvature;
            Vector3 segmentDirection;

            if (useCurvature)
            {
                float radius = Vector3.Distance(curvatureCenter, startPos);
                curvature = 1f / radius;
                if (curvature < 1e-6)
                {
                    curvature        = 0;
                    segmentDirection = endPos - startPos;
                    segmentDirection.Normalize();
                }
                else
                {
                    segmentDirection = CurveDirectionFromParent(startPos, endPos, curvatureCenter);
                }
            }
            else
            {
                curvature        = 0;
                segmentDirection = endPos - startPos;
                segmentDirection.Normalize();
            }

            float distance = ArcLengthFromChord(startPos, endPos, curvature);

            int numShells = Mathf.CeilToInt((Mathf.Max(startRadius, endRadius) -
                                             Mathf.Min(startRadius, endRadius)) / wallThickness);

            if (numShells < 2)
            {
                numShells = 2;
            }

            // int numShells = Mathf.CeilToInt(distance / Mathf.Min(startRadius, endRadius));

            // Length is just the distance we need to cover divided by the number of shells.
            float lengthPerShell = distance / numShells;
            // We attempt to choose the radii such that the telescope tapers from the start
            // radius to the end radius over the given number of shells.
            float radiusStep = (startRadius - endRadius) / numShells;

            float twist = 0;

            if (curvature >= 1e-6)
            {
                // Compute twist angles
                Quaternion rotationToOrigin = Quaternion.FromToRotation(Vector3.forward, segmentDirection);
                // The "up" direction we would like to have -- orthogonal direction from circle center.
                Vector3 startEnd  = endPos - startPos;
                Vector3 desiredUp = startEnd - Vector3.Dot(segmentDirection, startEnd) * segmentDirection;
                desiredUp.Normalize();
                Vector3 inverseDesired = Quaternion.Inverse(rotationToOrigin) * desiredUp;

                // The angle computation doesn't work right in 3rd and 4th quadrants,
                // so work around it by doing everything in 1st and 2nd.
                if (inverseDesired.x < 0)
                {
                    inverseDesired *= -1;
                    twist           = 180;
                }

                float angleBetween = Mathf.Atan2(Vector3.Cross(Vector3.up, inverseDesired).magnitude,
                                                 Vector3.Dot(Vector3.up, inverseDesired));

                twist += -angleBetween * Mathf.Rad2Deg;
            }

            List <TelescopeParameters> diffList = new List <TelescopeParameters>();

            // Create the initial shell parameters.
            TelescopeParameters initialParams = new TelescopeParameters(lengthPerShell, startRadius, wallThickness, curvature, 0, twist);

            diffList.Add(initialParams);
            // Create all the diffs.
            for (int i = 1; i < numShells; i++)
            {
                TelescopeParameters tp = new TelescopeParameters(0, -radiusStep, wallThickness, 0, 0, 0);
                diffList.Add(tp);
            }

            // Create a game object that will be the new segment.
            GameObject obj = new GameObject();

            obj.name = "segment" + segmentCount;
            segmentCount++;
            obj.transform.position = startPos;
            TelescopeSegment seg = obj.AddComponent <TelescopeSegment>();

            seg.material         = DesignerController.instance.defaultTelescopeMaterial;
            seg.initialDirection = segmentDirection;

            seg.MakeShellsFromDiffs(diffList);
            seg.transform.position = startPos;

            return(seg);
        }