public void UpdateRailSegment(int index, Vector3[] controlPoints)
        {
            RailSegment segment = RailSegments[index];

            segment.Curve.SetControlPoints(controlPoints);

            Definition.CreateGeometry(RailSegments);
        }
Beispiel #2
0
        private void PutLastWheelsetOnTrack()
        {
            float distance = Definition.DistanceFromFirstToLastWheelset * -FirstWheelsetDirectionOfT;

            LastWheelsetSegmentT     = FirstWheelsetSegmentT;
            LastWheelsetDirectionOfT = FirstWheelsetDirectionOfT;
            LastWheelsetSegment      = FirstWheelsetSegment.MoveSignedDistance(distance, ref LastWheelsetSegmentT, ref LastWheelsetDirectionOfT);
        }
Beispiel #3
0
        public void PutOnTrack(RailSegment firstWheelsetSegment, float firstWheelsetT, bool sameDirectionAsSegment)
        {
            FirstWheelsetSegment      = firstWheelsetSegment;
            FirstWheelsetSegmentT     = firstWheelsetT;
            FirstWheelsetDirectionOfT = sameDirectionAsSegment ? 1 : -1;

            PutLastWheelsetOnTrack();
        }
 public void RemoveRailSegment(RailSegment segment)
 {
     if (!RailSegments.Contains(segment))
     {
         return;
     }
     segment.Detach();
     RailSegments.Remove(segment);
 }
Beispiel #5
0
 public void RestorePreviousParameters()
 {
     FirstWheelsetSegment      = m_previousFirstWheelsetSegment;
     FirstWheelsetSegmentT     = m_previousFirstWheelsetSegmentT;
     FirstWheelsetDirectionOfT = m_previousFirstWheelsetDirectionOfT;
     LastWheelsetSegment       = m_previousLastWheelsetSegment;
     LastWheelsetSegmentT      = m_previousLastWheelsetSegmentT;
     LastWheelsetDirectionOfT  = m_previousLastWheelsetDirectionOfT;
 }
 public void Detach()
 {
     foreach (ConnectedSegmentInfo connectedSegmentInfo in ConnectedSegmentInfos)
     {
         RailSegment connectedSegment = connectedSegmentInfo.RailSegment;
         int         removeIndex      = connectedSegment.GetConnectionIndex(this);
         connectedSegment.ConnectedSegmentInfos.RemoveAt(removeIndex);
     }
     ConnectedSegmentInfos.Clear();
 }
 private int GetConnectionIndex(RailSegment segment)
 {
     for (int k = 0; k < ConnectedSegmentInfos.Count; k++)
     {
         if (ConnectedSegmentInfos[k].RailSegment == segment)
         {
             return(k);
         }
     }
     throw new ArgumentException("Given segment is not connected");
 }
Beispiel #8
0
        private void UpdateLastWheelsetPosition()
        {
            if (Definition.Wheelsets.Length == 1)
            {
                LastWheelsetSegment      = FirstWheelsetSegment;
                LastWheelsetSegmentT     = FirstWheelsetSegmentT;
                LastWheelsetDirectionOfT = FirstWheelsetDirectionOfT;
                return;
            }
            Vector3 firstWheelsetPosition = FirstWheelsetSegment.GetCurvePositionInWorldSpace(FirstWheelsetSegmentT);
            Vector3 lastWheelsetPosition  = LastWheelsetSegment.GetCurvePositionInWorldSpace(LastWheelsetSegmentT);
            float   wantedDistance        = Definition.DistanceFromFirstToLastWheelset;
            float   actualDistance        = (firstWheelsetPosition - lastWheelsetPosition).magnitude;
            float   distanceToMove        = LastWheelsetDirectionOfT * (actualDistance - wantedDistance);

            LastWheelsetSegment = LastWheelsetSegment.MoveSignedDistance(distanceToMove, ref LastWheelsetSegmentT, ref LastWheelsetDirectionOfT);
        }
Beispiel #9
0
        protected RailPiece(RailPieceDefinition definition, bool copyCurves, bool copyGeometry)
        {
            ID         = FirstUnusedID++;
            Definition = definition;
            GameObject = new GameObject("Rail piece " + ID);

            // Copy rail segments. Cannot share segments of definition,
            // because of next and previous fields in rail segments that must
            // be different for each rail piece instance.
            RailSegments = new RailSegment[definition.RailSegments.Length];
            for (int k = 0; k < RailSegments.Length; k++)
            {
                RailSegments[k] = new RailSegment(definition.RailSegments[k], this, copyCurves);
            }

            GameObject = (GameObject)Object.Instantiate(definition.GetPrefab());
            if (copyGeometry)
            {
            }
        }
        public void ConnectSegment(RailSegment segment, bool asPreviousSegment, bool segmentHasSameTDirection)
        {
            // Add segment to list of connected segments
            var segmentInfo = new ConnectedSegmentInfo
            {
                RailSegment    = segment,
                AsPrevious     = asPreviousSegment,
                SameTDirection = segmentHasSameTDirection
            };

            ConnectedSegmentInfos.Add(segmentInfo);

            // Add me to other segment's list of connected segments
            var otherSegmentInfo = new ConnectedSegmentInfo
            {
                RailSegment    = this,
                AsPrevious     = asPreviousSegment ? !segmentHasSameTDirection : segmentHasSameTDirection,
                SameTDirection = segmentHasSameTDirection
            };

            segment.ConnectedSegmentInfos.Add(otherSegmentInfo);
        }
        public void AddRailSegment(RailSegment segment)
        {
            if (RailSegments.Contains(segment))
            {
                // If the segment is in the list of rail segments, then
                // it is already connected to other segments in the list
                // and also should not be added to the list again
                return;
            }

            // Segment should not be connected to anything
            Debug.Assert(segment.ConnectedSegmentInfos.Count == 0);

            // Try to connect the segment to connectors of segments in the system
            foreach (RailSegment systemSegment in RailSegments)
            {
/*
 *                              Matrix systemTransform = systemSegment.WorldTransformation;
 *                              Matrix transform = segment.WorldTransformation;
 *
 *                              Vector3 systemCurveStartInWorldSpace = Vector3.Transform(systemSegment.Curve.GetPosition(0), systemTransform);
 *                              Vector3 systemCurveDirectionInWorldSpace = Vector3.TransformNormal(systemSegment.Curve.GetTangent(0), systemTransform);
 *
 *                              Vector3 curveStartInWorldSpace = Vector3.Transform(segment.Curve.GetPosition(0), transform);
 *                              Vector3 curveDirectionInWorldSpace = Vector3.TransformNormal(segment.Curve.GetTangent(0), transform);
 *
 *                              if (systemCurveStartInWorldSpace.EqualsWithEpsilon(curveStartInWorldSpace, ConnectionEpsilon) &&
 *                                      Vector3.Dot(systemCurveDirectionInWorldSpace, -curveDirectionInWorldSpace) > 0.9f)
 *                              {
 *                                      // Open connectors of both segments at t = 0 connect
 *                                      // I.E. tail-to-tail connection
 *                                      systemSegment.ConnectSegment(segment, true, false);
 *                              }
 *
 *                              Vector3 curveEndInWorldSpace = Vector3.Transform(segment.Curve.GetPosition(1), transform);
 *                              curveDirectionInWorldSpace = Vector3.TransformNormal(segment.Curve.GetTangent(1), transform);
 *
 *                              if (systemCurveStartInWorldSpace.EqualsWithEpsilon(curveEndInWorldSpace, ConnectionEpsilon) &&
 *                                      Vector3.Dot(systemCurveDirectionInWorldSpace, curveDirectionInWorldSpace) > 0.9f)
 *                              {
 *                                      // system segment's connector at t = 0 connects with segment's connector at t = 1
 *                                      // I.E. tail-to-head connection
 *                                      systemSegment.ConnectSegment(segment, true, true);
 *                              }
 *
 *                              Vector3 systemCurveEndInWorldSpace = Vector3.Transform(systemSegment.Curve.GetPosition(1), systemTransform);
 *                              systemCurveDirectionInWorldSpace = Vector3.TransformNormal(systemSegment.Curve.GetTangent(1), systemTransform);
 *
 *                              curveStartInWorldSpace = Vector3.Transform(segment.Curve.GetPosition(0), transform);
 *                              curveDirectionInWorldSpace = Vector3.TransformNormal(segment.Curve.GetTangent(0), transform);
 *
 *                              if (systemCurveEndInWorldSpace.EqualsWithEpsilon(curveStartInWorldSpace, ConnectionEpsilon) &&
 *                                      Vector3.Dot(systemCurveDirectionInWorldSpace, curveDirectionInWorldSpace) > 0.9f)
 *                              {
 *                                      // system segment's connector at t = 1 connects with segment's connector at t = 1
 *                                      // I.E. head-to-tail connection
 *                                      systemSegment.ConnectSegment(segment, false, true);
 *                              }
 *
 *                              curveEndInWorldSpace = Vector3.Transform(segment.Curve.GetPosition(1), transform);
 *                              curveDirectionInWorldSpace = Vector3.TransformNormal(segment.Curve.GetTangent(1), transform);
 *
 *                              if (systemCurveEndInWorldSpace.EqualsWithEpsilon(curveEndInWorldSpace, ConnectionEpsilon) &&
 *                                      Vector3.Dot(systemCurveDirectionInWorldSpace, -curveDirectionInWorldSpace) > 0.9f)
 *                              {
 *                                      // Open connectors of both segments at t = 1 connect
 *                                      // I.E. head-to-head connection
 *                                      systemSegment.ConnectSegment(segment, false, false);
 *                              }
 */
            }

            RailSegments.Add(segment);
        }
 public RailSegment(RailSegment source, RailPiece railPiece, bool copyCurve)
 {
     RailPiece = railPiece;
     Curve     = copyCurve ? new BezierCurve3(source.Curve) : source.Curve;
 }
        public RailSegment MoveSignedDistance(float signedDistance, ref float t, ref int directionAlongT)
        {
            // Move over the rail segment for the given distance, going to a next or previous
            // segment if the distance to move is bigger than the distance to the end of the curve of the segment.
            // If it is, subtract the remaining length on the curve from the distance to travel, set the new
            // segment as the current segment, and repeat.
            // The distance to move is signed indicating the direction to move over the segment(s). Positive means
            // in the same direction as curve parameter t (going from 0 to 1).
            // Segments can be connected in different ways (head to head, head to tail, etc). Variable XXX
            // is used to keep track of the direction on the curve. If true, we are moving from current curve parameter
            // t = <current> to t = 0. If false, we move towards t = 1

            float       remainingDistance   = Math.Abs(signedDistance);
            bool        movePositiveInitial = signedDistance > 0;
            bool        movePositive        = movePositiveInitial;
            RailSegment currentSegment      = this;

            while (remainingDistance > 0)
            {
                float curvePosition = currentSegment.Curve.GetLength(0, t);

                if (movePositive)
                {
                    // Moving over curve towards t = 1 (positive direction)
                    float remainingCurveLength = Curve.Length - curvePosition;
                    if (remainingDistance <= remainingCurveLength)
                    {
                        // More curve remaining than distance to move. Update time and done
                        curvePosition    += remainingDistance;
                        t                 = currentSegment.Curve.GetTime(curvePosition, 32, CurvePositionTolerance);
                        remainingDistance = 0;
                    }
                    else
                    {
                        // More distance to move than curve length remaining.
                        // Move to end of curve, set next curve as current (if it exists), and continue
                        remainingDistance -= remainingCurveLength;
                        ConnectedSegmentInfo connectedSegmentInfo = GetActiveConnectedSegment(false);
                        if (connectedSegmentInfo.RailSegment != null)
                        {
                            if (connectedSegmentInfo.SameTDirection)
                            {
                                t = 0;
                            }
                            else
                            {
                                movePositive = false;
                                t            = 1;
                            }
                            currentSegment = connectedSegmentInfo.RailSegment;
                        }
                        else
                        {
                            // No active next segment: end of track and done
                            currentSegment    = null;
                            remainingDistance = 0;
                            t = 1;
                        }
                    }
                }
                else
                {
                    // Moving over curve towards t = 0 (negative direction)
                    if (remainingDistance <= curvePosition)
                    {
                        // More curve remaining than distance to move. Update time and done
                        curvePosition    -= remainingDistance;
                        t                 = currentSegment.Curve.GetTime(curvePosition, 32, CurvePositionTolerance);
                        remainingDistance = 0;
                    }
                    else
                    {
                        // More distance to move than curve length remaining.
                        // Move to start of curve, set previous curve as current (if it exists), and continue
                        remainingDistance -= curvePosition;
                        ConnectedSegmentInfo connectedSegmentInfo = GetActiveConnectedSegment(true);
                        if (connectedSegmentInfo.RailSegment != null)
                        {
                            if (connectedSegmentInfo.SameTDirection)
                            {
                                t = 1;
                            }
                            else
                            {
                                movePositive = true;
                                t            = 0;
                            }
                            currentSegment = connectedSegmentInfo.RailSegment;
                        }
                        else
                        {
                            // No active previous segment: end of track and done
                            currentSegment    = null;
                            remainingDistance = 0;
                            t = 1;
                        }
                    }
                }
            }
            if (movePositive != movePositiveInitial)
            {
                directionAlongT = -directionAlongT;
            }
            return(currentSegment);
        }