Esempio n. 1
0
    public static Node[] MatchNodeCount(Node[] from, Node[] to, Spline fromSpline)
    {
        int fromCount  = from.Length;
        int toCount    = to.Length;
        int difference = toCount - fromCount;

        List <Node> tempNodeList = new List <Node>(from);

        if (fromCount != toCount)
        {
            for (int i = 0; i < difference; i++)
            {
                //Adds Node between last and before last spline

                SplineNode lastNode       = fromSpline.nodes[fromCount - 1];
                SplineNode formerLastNode = fromSpline.nodes[fromCount - 2];
                SplineNode firstNode      = fromSpline.nodes[0];

                float fullDist       = Vector3.Distance(lastNode.Position, firstNode.Position);
                float formerDist     = Vector3.Distance(formerLastNode.Position, firstNode.Position);
                float lastFormerDist = Vector3.Distance(formerLastNode.Position, lastNode.Position);

                float insertTime = ((lastFormerDist / 2) + formerDist) / fullDist;

                CurveSample insertNodeSample = GetSampleAt(fromSpline, insertTime);
                Node        insertNode       = new Node(insertNodeSample.location, insertNodeSample.tangent * 0.1f + insertNodeSample.location);
                tempNodeList.Insert(tempNodeList.Count - 1, insertNode);

                fromSpline.InsertNode(fromSpline.nodes.Count - 1, new SplineNode(insertNode.position, insertNode.handleOut));
            }
        }
        Node[] insertedNodeArray = tempNodeList.ToArray();

        return(insertedNodeArray);
    }
Esempio n. 2
0
    public static Spline MatchNodeCount(Spline from, Node[] to)
    {
        int fromCount  = from.nodes.Count;
        int toCount    = to.Length;
        int difference = toCount - fromCount;

        if (fromCount != toCount)
        {
            for (int i = 0; i < difference; i++)
            {
                //Adds Node between last and before last spline

                SplineNode lastNode       = from.nodes[fromCount - 1];
                SplineNode formerLastNode = from.nodes[fromCount - 2];
                SplineNode firstNode      = from.nodes[0];

                float fullDist       = Vector3.Distance(lastNode.Position, firstNode.Position);
                float formerDist     = Vector3.Distance(formerLastNode.Position, firstNode.Position);
                float lastFormerDist = Vector3.Distance(formerLastNode.Position, lastNode.Position);

                float insertTime = ((lastFormerDist / 2) + formerDist) / fullDist;

                CurveSample insertNode = GetSampleAt(from, insertTime);
                from.InsertNode(fromCount - 1, new SplineNode(insertNode.location, insertNode.tangent * 0.1f + insertNode.location));
            }
        }
        return(from);
    }
Esempio n. 3
0
        private void ComputePoints()
        {
            m_Samples.Clear();
            Length = 0;
            Vector3 previousPosition = GetLocation(0);

            for (float t = 0; t < 1; t += m_TStep)
            {
                CurveSample sample = new CurveSample();
                sample.location = GetLocation(t);
                sample.tangent  = GetTangent(t);
                Length         += Vector3.Distance(previousPosition, sample.location);
                sample.distance = Length;

                previousPosition = sample.location;
                m_Samples.Add(sample);
            }

            CurveSample lastSample = new CurveSample();

            lastSample.location = GetLocation(1);
            lastSample.tangent  = GetTangent(1);
            Length += Vector3.Distance(previousPosition, lastSample.location);
            lastSample.distance = Length;
            m_Samples.Add(lastSample);
        }
    //void Update()
    //{
    //    distance += Time.deltaTime / DurationInSecond;

    //    if (currentSpline != null)
    //    {
    //        if (distance > currentSpline.nodes.Count - 1)
    //        {
    //            distance = 0;

    //            // --- Beni - 11.20.
    //            // spline[0] has the complete track, so this logic is unneseccary and
    //            // causes a bug once the cart reaches the end of the track
    //            // since at the end of spline[0] we should not go spline[1]
    //            // but to the beggining of spline[0], since it has the complete track

    //            //GetNextSpline();

    //            // --- END
    //        }
    //    }
    //    PlaceFollower();
    //}

    private void PlaceFollower()
    {
        if (currentSpline != null)
        {
            if (Follower != null)
            {
                //// --- Beni 11.28.
                //// Changed to match contruder
                //// But it doesn't work because the spline length changes after generation
                //rate += Time.deltaTime / DurationInSecond;
                //if (rate > 1)
                //{
                //    rate--;
                //}
                //CurveSample sample = currentSpline.GetSampleAtDistance(currentSpline.Length * rate);
                //// --- END

                //CurveSample sample = currentSpline.GetSample(rate);
                CurveSample sample = currentSpline.GetSampleAtDistance(distance);
                Follower.transform.localPosition = currentSpline.WorldPosition(sample.location);
                Follower.transform.localRotation = sample.Rotation;
            }
        }
        else
        {
            currentSpline = SplineManager.instance.GetSplineComponent(splineCount);
        }
    }
    private CurveSample getCurvePointAtDistance(float d)
    {
        if (d < 0 || d > Length)
        {
            throw new ArgumentException("Distance must be positive and less than curve length. Length = " + Length + ", given distance was " + d);
        }

        CurveSample previous = samples[0];
        CurveSample next     = null;

        foreach (CurveSample cp in samples)
        {
            if (cp.distance >= d)
            {
                next = cp;
                break;
            }
            previous = cp;
        }
        if (next == null)
        {
            throw new Exception("Can't find curve samples.");
        }
        float t = next == previous ? 0 : (d - previous.distance) / (next.distance - previous.distance);

        CurveSample res = new CurveSample();

        res.distance = d;
        res.location = Vector3.Lerp(previous.location, next.location, t);
        res.tangent  = Vector3.Lerp(previous.tangent, next.tangent, t).normalized;
        return(res);
    }
Esempio n. 6
0
        public CurveSample NewIteration()
        {
            m_IterSampleIndex = 0;
            CurveSample sample = Iterate();

            return(sample);
        }
Esempio n. 7
0
    private void UpdateTransformOnSpline(GameObject objectToUpdate, Spline spline, float positionTime)
    {
        CurveSample p = Util.GetSampleAt(spline, positionTime);

        UpdatePositionOnSpline(objectToUpdate, p.location);
        UpdateRotationOnSpline(objectToUpdate, 0f, p.tangent);
    }
Esempio n. 8
0
        private CurveSample CatmullRom(int i, float u)
        {
            var sample = new CurveSample();

            //-----------
            // When u==0, just return the first point of the interval
            if (u <= 0)
            {
                sample.Pos = _controlPoints[i].pos;
                sample.Rot = _controlPoints[i].rot;
                sample.U   = 0;
                return(sample);
            }

            //----------
            // Position
            var p1 = _controlPoints[i].pos;
            var p0 = p1;

            if (i > 0)
            {
                p0 = _controlPoints[i].pos;
            }
            var p2 = _controlPoints[i + 1].pos;
            var p3 = p2;

            if (i + 2 < _controlPoints.Count)
            {
                p3 = _controlPoints[i + 2].pos;
            }

            var tens = speedMultiplier;
            var u2   = u * u;
            var u3   = u2 * u;

            sample.Pos = (-tens * u + 2 * tens * u2 - tens * u3) * p0 +
                         (1 + (tens - 3) * u2 + (2 - tens) * u3) * p1 +
                         (tens * u + (3 - 2 * tens) * u2 + (tens - 2) * u3) * p2 +
                         (tens * u3 - tens * u2) * p3;

            //----------
            // Rotation
            var t1 = _controlPoints[i];
            var t2 = _controlPoints[i + 1];

            sample.Rot = _prevPoint.Rot;

            // Keep the forward tangent to the curve
            var tg = (sample.Pos - _prevPoint.Pos);
            var up = Vector3.Cross(tg, Vector3.Lerp(t1.right, t2.right, u));

            if ((up.magnitude > 0) && (tg.magnitude > 0))
            {
                sample.Rot = Quaternion.LookRotation(tg, up);
            }

            sample.U = u;

            return(sample);
        }
Esempio n. 9
0
        private CurveSample getCurvePointAtDistance(float d)
        {
            d = Mathf.Clamp(d, 0, Length);

            CurveSample previous = m_Samples[0];
            CurveSample next     = m_Samples[m_StepCount - 1];

            for (int i = 0; i < m_StepCount; i++)
            {
                CurveSample cp = m_Samples[i];

                if (cp.distance >= d)
                {
                    next = cp;
                    break;
                }

                previous = cp;
            }

            if (next == null)
            {
                throw new Exception("Can't find curve samples.");
            }

            float t = next == previous ? 0 : (d - previous.distance) / (next.distance - previous.distance);

            CurveSample res = new CurveSample();

            res.distance = d;
            res.location = Vector3.Lerp(previous.location, next.location, t);
            res.tangent  = Vector3.Lerp(previous.tangent, next.tangent, t).normalized;

            return(res);
        }
Esempio n. 10
0
        /// <summary>
        /// Following spline progressively.
        /// </summary>
        void Update()
        {
            if (!_isOk)
            {
                return;
            }

            _posOnSpline += Time.deltaTime * (speedInUnitsPerSecond / _splineRef.Length);

            // Don't query for position outside curve bounds
            _posOnSpline = Mathf.Clamp(_posOnSpline, 0.0f, 1.0f);

            CurveSample sample = _splineRef.GetSampleAtDistance(_posOnSpline * _splineRef.Length);

            // Add Spline object position offset
            if (_splineParent)
            {
                transform.position = (_splineParent.rotation * sample.location) + _splineRef.transform.position;
            }
            else
            {
                transform.position = sample.location + _splineRef.transform.position;
            }

            if (gameObject.tag != "Projectile")
            {
                transform.rotation = sample.Rotation;
            }
        }
    private void ComputePoints()
    {
        samples.Clear();
        Length = 0;
        Vector3 previousPosition = GetLocation(0);

        for (float t = 0; t < 1; t += T_STEP)
        {
            CurveSample sample = new CurveSample();
            sample.location = GetLocation(t);
            sample.tangent  = GetTangent(t);
            Length         += Vector3.Distance(previousPosition, sample.location);
            sample.distance = Length;

            previousPosition = sample.location;
            samples.Add(sample);
        }
        CurveSample lastSample = new CurveSample();

        lastSample.location = GetLocation(1);
        lastSample.tangent  = GetTangent(1);
        Length += Vector3.Distance(previousPosition, lastSample.location);
        lastSample.distance = Length;
        samples.Add(lastSample);

        if (Changed != null)
        {
            Changed.Invoke();
        }
    }
Esempio n. 12
0
    private void UpdateLeafTransform(GameObject leaf, Spline spline, float position, float yRotation, float localScale)
    {
        CurveSample p = Util.GetSampleAt(spline, position);

        leaf.transform.position   = p.location + transform.position;
        leaf.transform.rotation   = Quaternion.Euler(0, yRotation, Vector3.Angle(Vector3.up, p.tangent));
        leaf.transform.localScale = Vector3.one * localScale;
    }
Esempio n. 13
0
 private void PlaceFollower()
 {
     if (generated != null)
     {
         CurveSample sample = spline.GetSample(rate);
         generated.transform.localPosition = sample.location;
     }
 }
Esempio n. 14
0
        private CurveSample Hermite(int i, float u)
        {
            var sample = new CurveSample();

            //-----------
            // When u==0, just return the first point of the interval
            if (u <= 0)
            {
                sample.Pos = _controlPoints[i].pos;
                sample.Rot = _controlPoints[i].rot;
                sample.U   = 0;
                return(sample);
            }

            //----------
            // Position
            var p0 = _controlPoints[i].pos;
            var p1 = _controlPoints[i + 1].pos;
            var v0 = _controlPoints[i].forward * speedMultiplier;
            var v1 = _controlPoints[i + 1].forward * speedMultiplier;

            var u2 = u * u;
            var u3 = u2 * u;

            sample.Pos = (1 - 3 * u2 + 2 * u3) * p0 +
                         u2 * (3 - 2 * u) * p1 +
                         u * (u - 1) * (u - 1) * v0 +
                         u2 * (u - 1) * v1;

            //----------
            // Rotation
            var t1 = _controlPoints[i];
            var t2 = _controlPoints[i + 1];

            sample.Rot = _prevPoint.Rot;

            // Keep the forward tangent to the curve
            var tg = (sample.Pos - _prevPoint.Pos);

            tg.Normalize();
            var up = Vector3.Cross(tg, Vector3.Lerp(t1.right, t2.right, u));

            //var up = Vector3.Cross(tg, t1.right);

            //Debug.Log(sample.Pos.x);

            if ((up.magnitude > 0) && (tg.magnitude > 0))
            {
                sample.Rot = Quaternion.LookRotation(tg, up);
            }
            else
            {
                Debug.Log("error magnitude tg up");
            }

            sample.U = u;
            return(sample);
        }
Esempio n. 15
0
 private void PlaceFollower()
 {
     if (m_Spline != null)
     {
         CurveSample sample = m_Spline.GetSample(rate);
         transform.localPosition = sample.location;
         transform.localRotation = sample.Rotation;
     }
 }
Esempio n. 16
0
    private void UpdateTransformOnSpline(GameObject objectToUpdate, Spline spline, float positionTime, float yEulerAngle, float localScale)
    {
        CurveSample p = Util.GetSampleAt(spline, positionTime);

        UpdatePositionOnSpline(objectToUpdate, p.location);
        UpdateRotationOnSpline(objectToUpdate, yEulerAngle, p.tangent);
        UpdateLocalScale(objectToUpdate, localScale);
        objectToUpdate.transform.RotateAround(transform.position, Vector3.up, _d.Rotation);
    }
Esempio n. 17
0
    void PFConstSpeed()
    {
        locationOnSpline += Time.deltaTime * speed;
        locationOnSpline %= spline.Length;
        CurveSample sample = spline.GetSampleAtDistance(locationOnSpline);

        follower.transform.position      = sample.location;
        follower.transform.localRotation = sample.Rotation;
    }
Esempio n. 18
0
        public CurveSample Iterate()
        {
            if (m_IterSampleIndex >= m_StepCount)
            {
                return(null);
            }

            CurveSample sample = m_Samples[m_IterSampleIndex++];

            return(sample);
        }
Esempio n. 19
0
        private CurveSample Lineal(int i, float u)
        {
            var sample = new CurveSample();

            var t1 = _controlPoints[i];
            var t2 = _controlPoints[i + 1];

            sample.Pos = Vector3.Lerp(t1.pos, t2.pos, u);
            sample.Rot = Quaternion.Slerp(t1.rot, t2.rot, u);
            sample.U   = u;

            return(sample);
        }
Esempio n. 20
0
    void PFZeroToOne()
    {
        float playerInput = controls.Player.Forward.ReadValue <float>() - controls.Player.Reverse.ReadValue <float>();

        locationOnSpline = Mathf.Clamp(spline.Length, 0, 20) * playerInput;
        if (locationOnSpline < 0)
        {
            locationOnSpline += spline.Length;
        }

        CurveSample sample = spline.GetSampleAtDistance(locationOnSpline);

        follower.transform.position      = sample.location;
        follower.transform.localRotation = sample.Rotation;
    }
Esempio n. 21
0
    void PFVelocityControl()
    {
        float playerInput = controls.Player.Forward.ReadValue <float>() - controls.Player.Reverse.ReadValue <float>();

        locationOnSpline += playerInput * Time.deltaTime * speed;
        if (locationOnSpline < 0)
        {
            locationOnSpline += spline.Length;
        }
        locationOnSpline %= spline.Length;

        CurveSample sample = spline.GetSampleAtDistance(locationOnSpline);

        follower.transform.position      = sample.location;
        follower.transform.localRotation = sample.Rotation;
    }
    private void MoveFollower(float newDistanceAlongSpline)
    {
        if (spline == null || follower == null)
        {
            return;
        }

        CurveSample lengthSample = spline.GetSampleAtDistance(newDistanceAlongSpline);
        // CurveSample lengthSample = spline.GetSample(progress * (spline.nodes.Count - 1));    // For getting the sample weighted by nodes

        var     transform     = follower.transform;
        Vector3 localPosition = lengthSample.location;

        transform.localPosition = localPosition;
        transform.localRotation = lengthSample.Rotation;
    }
    /// <summary>
    /// Instantiate the prefabs here
    /// </summary>
    public void Sow()
    {
        UOUtility.DestroyChildren(generated);

        UnityEngine.Random.InitState(randomSeed);
        if (spacing + spacingRange <= 0 || prefab == null)
        {
            return;
        }

        float distance = 0;

        while (distance <= spline.Length)
        {
            CurveSample sample = spline.GetSampleAtDistance(distance);

            GameObject go;
            go = Instantiate(prefab, generated.transform);
            go.transform.localRotation = Quaternion.identity;
            go.transform.localPosition = Vector3.zero;
            go.transform.localScale    = Vector3.one;

            // move along spline, according to spacing + random
            go.transform.localPosition = sample.location;
            // apply scale + random
            float rangedScale = scale + UnityEngine.Random.Range(0, scaleRange);
            go.transform.localScale = new Vector3(rangedScale, rangedScale, rangedScale);
            // rotate with random yaw
            if (isRandomYaw)
            {
                go.transform.Rotate(0, 0, UnityEngine.Random.Range(-180, 180));
            }
            else
            {
                go.transform.rotation = sample.Rotation;
            }

            // move orthogonaly to the spline, according to offset + random
            var binormal    = (Quaternion.LookRotation(sample.tangent, sample.up) * Vector3.right).normalized;
            var localOffset = offset + UnityEngine.Random.Range(0, offsetRange * Math.Sign(offset));
            localOffset           *= sample.scale.x;
            binormal              *= localOffset;
            go.transform.position += binormal;

            distance += spacing + UnityEngine.Random.Range(0, spacingRange);
        }
    }
Esempio n. 24
0
 // Place Objects
 void GenerateObjects()
 {
     // Keep generating objects until the end is reached
     while (count <= numNodes)
     {
         //move along the spline
         CurveSample sample = spline.GetSample(count);
         Vector3     splineLocalLocation = sample.location; //location tracked 2 parents up
         splineLocation = extruders[0].transform.TransformPoint(splineLocalLocation);
         splineRotation = sample.Rotation;                  //rotation tracked 1 parent up, camera being in same level but above
         splineTan      = sample.tangent;
         splineUp       = sample.up;
         Ring(splineLocation);
         //splineDir = spline.GetComponent<Spline>().GetSample(count).Direction;
         //Instantiate(item, splineLocation, splineRotation);
         count += .04f;
     }
 }
    private void FixedUpdate()
    {
        if (!path.IsLoop)
        {
            /*
             * //Add or Subtract the spline position based on what direction we need the platform to move. If the timer is greater than the spline's length
             * //or less than 0, we change direction
             * if (!Back) Position += Time.fixedDeltaTime * speed;
             * else Position -= Time.fixedDeltaTime * speed;
             * if (Position >= 0.99f && !Back)
             * {
             *  t = 1;
             *  Back = true;
             * }
             * if (Position <= 0.01f && Back) Back = false;
             */

            t        = Mathf.PingPong(Time.time * speed, 1f);
            Position = Mathf.Lerp(0, 1, LinearMovementCurve.Evaluate(t));
        }
        else
        {
            //If the spline path is a loop, we simply set the timer to 0 if it reaches the end.
            Position += Time.fixedDeltaTime * speed;
            if (Position >= 0.99f)
            {
                Position = 0;
            }
        }
        //Get the delta position
        CurrentPos = platform.position;
        if (PreviousPos != CurrentPos)
        {
            deltaPosition = CurrentPos - PreviousPos;
            PreviousPos   = CurrentPos;
        }
        //Then we get the position we need on the spline based on the timer, and move the platform to it.
        //Since SplineMesh returns spline positions in local space, we need to use TransformPoint to get it in world space.
        CurveSample p_sample = path.GetSampleAtDistance(Position * Length);

        platform.MovePosition(transform.TransformPoint(p_sample.location));
    }
Esempio n. 26
0
    //--METHODS

    public void PlaceOnSpline(Spline spline)
    {
        if (locationOnSpline.x < 0)
        {
            locationOnSpline.x += spline.Length;
        }
        locationOnSpline.x %= spline.Length;

        CurveSample sample   = spline.GetSampleAtDistance(locationOnSpline.x);
        Vector3     location = sample.location + (transform.right * locationOnSpline.z) + (transform.up * locationOnSpline.y);

        if (useParentSpline)
        {
            transform.localPosition = location;
            transform.localRotation = sample.Rotation;
        }
        else
        {
            transform.position = location + spline.transform.position;
            transform.rotation = sample.Rotation;
        }
    }
    private void FixedUpdate()
    {
        if (activeSpline != null)
        {
            //Get Sonic's current position along the spline
            CurveSample cur = activeSpline.GetSampleAtDistance(GetClosestPos(Player.rigidBody.position));

            //Get the Right vector of the current spline position so we can accurately adjust Sonic's velocity
            Vector3 SplinePlane = Vector3.Cross(cur.tangent, cur.up);

            //Project the vector onto the plane
            Player.rigidBody.velocity = Vector3.ProjectOnPlane(Player.rigidBody.velocity, SplinePlane);

            //Project the input too
            Player.InputDir = Vector3.ProjectOnPlane(Player.InputDir, SplinePlane);

            //Set the Player's position along the spline plane
            Vector3 NewPos = activeSpline.transform.TransformPoint(cur.location);
            NewPos.y = Player.rigidBody.position.y;
            Debug.DrawLine(transform.position, NewPos);
            Player.rigidBody.position = Vector3.MoveTowards(Player.rigidBody.position, NewPos, 1f);
        }
    }
Esempio n. 28
0
        void Update()
        {
            if (!_isOk)
            {
                return;
            }

            _posOnSpline += Time.deltaTime * (speedInUnitsPerSecond / _splineRef.Length);

            // Don't query for position outside curve bounds
            _posOnSpline = Mathf.Clamp(_posOnSpline, 0.0f, 1.0f);

            CurveSample sample = _splineRef.GetSampleAtDistance(_posOnSpline * _splineRef.Length);

            // Add Spline object position offset
            transform.position = sample.location + _splineRef.transform.position;
            transform.rotation = sample.Rotation;

            // Reset
            if (Math.Abs(_posOnSpline - 1.0f) < 0.0001f)
            {
                _posOnSpline = 0.0f;
            }
        }
Esempio n. 29
0
    void DuplicateOP()
    {
        if (m_Spline != null & m_Prefab != null && m_Generated != null)
        {
            UOUtility.DestroyChildren(m_Generated);

            UnityEngine.Random.InitState(m_RandomSeed);
            if (m_Spacing + m_SpacingRange <= 0 ||
                m_Prefab == null)
            {
                return;
            }

            float distance = 0;
            while (distance <= m_Spline.Length)
            {
                CurveSample sample = m_Spline.GetSampleAtDistance(distance);

                GameObject go;
                go = Instantiate(m_Prefab, m_Generated.transform);
                go.transform.localRotation = Quaternion.identity;
                go.transform.localPosition = Vector3.zero;
                go.transform.localScale    = Vector3.one;

                // move along spline, according to spacing + random
                go.transform.localPosition = sample.location;
                // apply scale + random
                float rangedScale = m_Scale + UnityEngine.Random.Range(0, m_ScaleRange);
                go.transform.localScale = new Vector3(rangedScale, rangedScale, rangedScale);
                switch (m_RotationMode)
                {
                case (RotationMode.FollowSplineNormal):
                    go.transform.rotation = sample.Rotation;

                    break;

                case (RotationMode.CustomRotation):
                    go.transform.Rotate(m_Rotation);
                    break;

                case (RotationMode.Combined):
                    go.transform.rotation  = sample.Rotation;
                    go.transform.rotation *= Quaternion.Euler(m_Rotation);
                    break;
                }
                // // rotate with random yaw
                if (m_RandomizeRotation)
                {
                    float RandomRange = UnityEngine.Random.Range(m_MinRange, m_MaxRange);
                    go.transform.rotation *= Quaternion.Euler(RandomRange, RandomRange, RandomRange);
                }

                // move orthogonaly to the spline, according to offset + random
                Vector3 binormal    = Vector3.zero;
                float   localOffset = 1.0f;
                switch (m_OffsetAxiz)
                {
                case OffsetAxis.X:
                    binormal     = (Quaternion.LookRotation(sample.tangent, sample.up) * Vector3.right).normalized;
                    localOffset  = m_Offset + UnityEngine.Random.Range(0, m_OffsetRange * Math.Sign(m_Offset));
                    localOffset *= sample.scale.x;
                    break;

                case OffsetAxis.Y:
                    binormal     = (Quaternion.LookRotation(sample.tangent, sample.up) * Vector3.up).normalized;
                    localOffset  = m_Offset + UnityEngine.Random.Range(m_OffsetRange * Math.Sign(m_Offset), 0);
                    localOffset *= sample.scale.y;
                    break;
                }


                binormal *= localOffset;
                go.transform.position += binormal;

                distance += m_Spacing + UnityEngine.Random.Range(0, m_SpacingRange);
            }
        }
    }
Esempio n. 30
0
        public override void Generate()
        {
            double tCurveLen            = CurveUtils.ArcLength(Curve);
            SampledArcLengthParam pAxis = new SampledArcLengthParam(Axis, Axis.Length);
            double tAxisLen             = pAxis.ArcLength;
            double tScale = tAxisLen / tCurveLen;

            int nRings       = Curve.Length;
            int nRingSize    = (NoSharedVertices) ? Slices + 1 : Slices;
            int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1;

            if (Capped == false)
            {
                nCapVertices = 0;
            }

            vertices = new VectorArray3d(nRingSize * nRings + 2 * nCapVertices);
            uv       = new VectorArray2f(vertices.Count);
            normals  = new VectorArray3f(vertices.Count);

            int nSpanTris = (nRings - 1) * (2 * Slices);
            int nCapTris  = (Capped) ? 2 * Slices : 0;

            triangles = new IndexArray3i(nSpanTris + nCapTris);

            float fDelta = (float)((Math.PI * 2.0) / Slices);

            double      tCur = 0;
            CurveSample s    = pAxis.Sample(tCur);
            Frame3f     f0   = new Frame3f((Vector3F)s.position, (Vector3F)s.tangent, 1);
            Frame3f     fCur = f0;

            // generate tube
            for (int ri = 0; ri < nRings; ++ri)
            {
                if (ri > 0)
                {
                    tCur       += (Curve[ri] - Curve[ri - 1]).Length;
                    s           = pAxis.Sample(tCur * tScale);
                    fCur.Origin = (Vector3F)s.position;
                    fCur.AlignAxis(1, (Vector3F)s.tangent);
                }

                Vector3D v_along  = Curve[ri];
                Vector3F v_frame  = fCur.ToFrameP((Vector3F)v_along);
                float    uv_along = (float)ri / (float)(nRings - 1);

                // generate vertices
                int nStartR = ri * nRingSize;
                for (int j = 0; j < nRingSize; ++j)
                {
                    float angle = (float)j * fDelta;

                    // [TODO] this is not efficient...use Matrix3f?
                    Vector3F v_rot = Quaternionf.AxisAngleR(Vector3F.AxisY, angle) * v_frame;
                    Vector3D v_new = fCur.FromFrameP(v_rot);
                    int      k     = nStartR + j;
                    vertices[k] = v_new;

                    float uv_around = (float)j / (float)(nRingSize);
                    uv[k] = new Vector2F(uv_along, uv_around);

                    // [TODO] proper normal
                    Vector3F n = (Vector3F)(v_new - fCur.Origin).Normalized;
                    normals[k] = n;
                }
            }


            // generate triangles
            int ti = 0;

            for (int ri = 0; ri < nRings - 1; ++ri)
            {
                int r0 = ri * nRingSize;
                int r1 = r0 + nRingSize;
                for (int k = 0; k < nRingSize - 1; ++k)
                {
                    triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise);
                    triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise);
                }
                if (NoSharedVertices == false)        // close disc if we went all the way
                {
                    triangles.Set(ti++, r1 - 1, r0, r1, Clockwise);
                    triangles.Set(ti++, r1 - 1, r1, r1 + nRingSize - 1, Clockwise);
                }
            }



            if (Capped)
            {
                // find avg start loop size
                Vector3D vAvgStart = Vector3D.Zero, vAvgEnd = Vector3D.Zero;
                for (int k = 0; k < Slices; ++k)
                {
                    vAvgStart += vertices[k];
                    vAvgEnd   += vertices[(nRings - 1) * nRingSize + k];
                }
                vAvgStart /= (double)Slices;
                vAvgEnd   /= (double)Slices;

                Frame3f fStart = f0;
                fStart.Origin = (Vector3F)vAvgStart;
                Frame3f fEnd = fCur;
                fEnd.Origin = (Vector3F)vAvgEnd;



                // add endcap verts
                int nBottomC = nRings * nRingSize;
                vertices[nBottomC]  = fStart.Origin;
                uv[nBottomC]        = new Vector2F(0.5f, 0.5f);
                normals[nBottomC]   = -fStart.Z;
                startCapCenterIndex = nBottomC;

                int nTopC = nBottomC + 1;
                vertices[nTopC]   = fEnd.Origin;
                uv[nTopC]         = new Vector2F(0.5f, 0.5f);
                normals[nTopC]    = fEnd.Z;
                endCapCenterIndex = nTopC;

                if (NoSharedVertices)
                {
                    // duplicate first loop and make a fan w/ bottom-center
                    int nExistingB = 0;
                    int nStartB    = nTopC + 1;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartB + k] = vertices[nExistingB + k];
                        //uv[nStartB + k] = (Vector2f)Polygon.Vertices[k].Normalized;

                        float  angle = (float)k * fDelta;
                        double cosa = Math.Cos(angle), sina = Math.Sin(angle);
                        uv[nStartB + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina));

                        normals[nStartB + k] = normals[nBottomC];
                    }
                    append_disc(Slices, nBottomC, nStartB, true, Clockwise, ref ti);

                    // duplicate second loop and make fan
                    int nExistingT = nRingSize * (nRings - 1);
                    int nStartT    = nStartB + Slices;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartT + k] = vertices[nExistingT + k];
                        //uv[nStartT + k] = (Vector2f)Polygon.Vertices[k].Normalized;

                        float  angle = (float)k * fDelta;
                        double cosa = Math.Cos(angle), sina = Math.Sin(angle);
                        uv[nStartT + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina));


                        normals[nStartT + k] = normals[nTopC];
                    }
                    append_disc(Slices, nTopC, nStartT, true, !Clockwise, ref ti);
                }
                else
                {
                    append_disc(Slices, nBottomC, 0, true, Clockwise, ref ti);
                    append_disc(Slices, nTopC, nRingSize * (nRings - 1), true, !Clockwise, ref ti);
                }
            }
        }