示例#1
0
        public void Initialize(List <RedLine> lines)
        {
            Clear();
            if (lines.Count == 0)
            {
                return;
            }
            //max size for init
            var          redshapes = new GenericVertex[lines.Count * ShapeSize * 3][];
            ResourceSync initsync  = new ResourceSync();
            int          vertcount = 0;

            System.Threading.Tasks.Parallel.For(0, lines.Count,
                                                (idx) =>
            {
                var acc        = GetAccelDecor(lines[idx]);
                redshapes[idx] = acc;
                System.Threading.Interlocked.Add(ref vertcount, acc.Length);
            });
            GenericVertex[] verts = new GenericVertex[vertcount];
            _indices.EnsureCapacity(vertcount);
            _indices.UnsafeSetCount(vertcount);
            int shapepos = 0;

            for (int idx = 0; idx < lines.Count; idx++)
            {
                var acc   = redshapes[idx];
                var entry = new accelentry()
                {
                    start  = shapepos,
                    shapes = acc.Length / ShapeSize
                };
                for (int i = 0; i < acc.Length; i++)
                {
                    verts[shapepos] = acc[i];
                    _indices.unsafe_array[shapepos] = shapepos;
                    shapepos++;
                }
                _lookup.Add(lines[idx].ID, entry);
            }


            _vertcount = verts.Length;
            _accelbuffer.Bind();
            EnsureVBOSize(verts.Length, false);
            _accelbuffer.SetData(verts, 0, 0, verts.Length);
            _accelbuffer.Unbind();
            _accelibo.Bind();
            EnsureIBOSize(_indices.Count, false);
            _accelibo.SetData(_indices.unsafe_array, 0, 0, _indices.Count);
            _accelibo.Unbind();
        }
示例#2
0
        /// <summary>
        /// The meat of the recompute engine, updating hit test and the
        /// cached frames.
        /// </summary>
        private void ThreadUnsafeRunFrames(int start, int count)
        {
            var   steps         = new Rider[count];
            var   collisionlist = new List <LinkedList <int> >(count);
            Rider current       = _frames[start - 1];
            int   framecount    = _frames.Count;
            var   bones         = _track.Bones;

            using (changesync.AcquireWrite())
            {
                // we use the savedcells buffer exactly so runframes can
                // be completely consistent with the track state at the
                // time of running

                // we could also get a lock on the track grid, but that would
                // block user input on the track until we finish running.
                _savedcells.Clear();
            }
            using (var sync = changesync.AcquireRead())
            {
                _hittest.MarkFirstInvalid(start);
                for (int i = 0; i < count; i++)
                {
                    int currentframe = start + i;
                    var collisions   = new LinkedList <int>();
                    current = current.Simulate(
                        _savedcells,
                        bones,
                        _activetriggers,
                        collisions);
                    steps[i] = current;
                    collisionlist.Add(collisions);
                    // 10 seconds of frames,
                    // couldnt hurt to check?
                    if ((i + 1) % 400 == 0)
                    {
                        sync.ReleaseWaiting();
                    }
                }
                _hittest.AddFrames(collisionlist);
            }
            if (start + count > framecount)
            {
                _frames.EnsureCapacity(start + count);
                _frames.UnsafeSetCount(start + count);
            }
            for (int i = 0; i < steps.Length; i++)
            {
                _frames.unsafe_array[start + i] = steps[i];
            }
            FrameInvalidated?.Invoke(this, start);
        }
示例#3
0
        public virtual Vector2d GetFrameCamera(int frame)
        {
            if (_zoom != _cachezoom)
            {
                _cachezoom = _zoom;
                _prevframe = -1;
                _framecache.UnsafeSetCount(1);
            }
            EnsureFrame(frame);
            var offset = CalculateOffset(frame);

            _prevframe  = frame;
            _prevcamera = offset;
            return(_frames[frame].RiderCenter + offset);
        }
示例#4
0
        /// <summary>
        /// The meat of the recompute engine, updating hit test and the
        /// cached frames.
        /// </summary>
        private void ThreadUnsafeRunFrames(int start, int count)
        {
            var       steps         = new frameinfo[count];
            var       collisionlist = new List <LinkedList <int> >(count);
            frameinfo current       = _frames[start - 1];
            int       framecount    = _frames.Count;
            var       bones         = _track.Bones;

            using (changesync.AcquireWrite())
            {
                // we use the savedcells buffer exactly so runframes can
                // be completely consistent with the track state at the
                // time of running

                // we could also get a lock on the track grid, but that would
                // block user input on the track until we finish running.
                _savedcells.Clear();
            }
            using (var sync = changesync.AcquireRead())
            {
                _hittest.MarkFirstInvalid(start);
                for (int i = 0; i < count; i++)
                {
                    int currentframe = start + i;
                    var collisions   = new LinkedList <int>();
                    var oldtrigid    = current.TriggerLineID;
                    var zoom         =
                        current.Rider = current.Rider.Simulate(
                            _savedcells,
                            bones,
                            ref current.TriggerLineID,
                            collisions,
                            frameid: currentframe);
                    if (current.TriggerLineID != oldtrigid)
                    {
                        current.TriggerHitFrame = currentframe;
                    }
                    if (current.TriggerLineID != -1)
                    {
                        var std = (StandardLine)_track.LineLookup[current.TriggerLineID];
                        Debug.Assert(std.Trigger != null, "Trigger line proc on line with no trigger");
                        var delta = currentframe - current.TriggerHitFrame;
                        if (!std.Trigger.Activate(delta, ref current.Zoom))
                        {
                            current.TriggerLineID   = -1;
                            current.TriggerHitFrame = -1;
                        }
                    }
                    steps[i] = current;
                    collisionlist.Add(collisions);

                    // 10 seconds of frames,
                    // couldnt hurt to check?
                    if ((i + 1) % 400 == 0)
                    {
                        sync.ReleaseWaiting();
                    }
                }
                _hittest.AddFrames(collisionlist);
            }
            if (start + count > framecount)
            {
                _frames.EnsureCapacity(start + count);
                _frames.UnsafeSetCount(start + count);
            }
            for (int i = 0; i < steps.Length; i++)
            {
                _frames.unsafe_array[start + i] = steps[i];
            }
            FrameInvalidated?.Invoke(this, start);
        }
示例#5
0
        /// <summary>
        /// Clears the renderer and initializes it with new lines.
        /// </summary>
        public void InitializeTrack(Track track)
        {
            AutoArray <GameLine> scenery = new AutoArray <GameLine>(track.SceneryLines);

            scenery.UnsafeSetCount(track.SceneryLines);
            AutoArray <GameLine> phys  = new AutoArray <GameLine>(track.BlueLines);
            AutoArray <GameLine> accel = new AutoArray <GameLine>(track.RedLines);
            var sorted = track.GetSortedLines();

            using (_sync.AcquireWrite())
            {
                _lineactions.Clear();
                _physvbo.Clear();
                _sceneryvbo.Clear();
                _accelvbo.Clear();
                _bluedecorator.Clear();
                _acceldecorator.Clear();
                _physlines.Clear();
                _scenerylines.Clear();
                _accellines.Clear();
                RequiresUpdate = true;

                int scenerycount = 0;
                for (int i = 0; i < sorted.Length; i++)
                {
                    var line = sorted[i];

                    switch (line.Type)
                    {
                    case LineType.Scenery:
                        scenery.unsafe_array[scenery.Count - (1 + scenerycount++)] = line;
                        break;

                    case LineType.Blue:
                        phys.Add(line);
                        break;

                    case LineType.Red:
                        accel.Add(line);
                        break;
                    }
                }

                Debug.Assert(scenerycount == scenery.Count,
                             "Predicted scenery count was not accurate");
                if (scenery.Count != 0)
                {
                    LineVertex[] sceneryverts = new LineVertex[scenery.Count * linesize];
                    System.Threading.Tasks.Parallel.For(0, scenery.Count, (index) =>
                    {
                        int counter = 0;
                        var verts   = (GenerateLine(scenery[index], false));
                        foreach (var vert in verts)
                        {
                            sceneryverts[index * linesize + counter++] = vert;
                        }
                    });
                    _scenerylines = _sceneryvbo.AddLines(
                        scenery,
                        sceneryverts);
                }
                if (phys.Count != 0)
                {
                    LineVertex[] physverts = new LineVertex[phys.Count * linesize];
                    System.Threading.Tasks.Parallel.For(0, phys.Count, (index) =>
                    {
                        int counter = 0;
                        var verts   = (GenerateLine(phys[index], false));
                        foreach (var vert in verts)
                        {
                            physverts[index * linesize + counter++] = vert;
                        }
                    });
                    _physlines = _physvbo.AddLines(
                        phys,
                        physverts);
                    _bluedecorator.Initialize(phys);
                }
                if (accel.Count != 0)
                {
                    LineVertex[] accelverts = new LineVertex[accel.Count * linesize];
                    System.Threading.Tasks.Parallel.For(0, accel.Count, (index) =>
                    {
                        int counter = 0;
                        var verts   = (GenerateLine(accel[index], false));
                        foreach (var vert in verts)
                        {
                            accelverts[index * linesize + counter++] = vert;
                        }
                    });
                    _accellines = _accelvbo.AddLines(
                        accel,
                        accelverts);
                    _acceldecorator.Initialize(accel);
                }
                RequiresUpdate = true;
            }
        }
示例#6
0
        /// <summary>
        /// The meat of the recompute engine, updating hit test and the
        /// cached frames.
        /// </summary>
        public void ThreadUnsafeRunFrames(int start, int count)
        {
            var       steps         = new frameinfo[count];
            var       collisionlist = new List <LinkedList <int> >(count);
            frameinfo current       = _frames[start - 1];
            int       framecount    = _frames.Count;
            var       bones         = _track.Bones;

            using (changesync.AcquireWrite())
            {
                // we use the savedcells buffer exactly so runframes can
                // be completely consistent with the track state at the
                // time of running

                // we could also get a lock on the track grid, but that would
                // block user input on the track until we finish running.
                _savedcells.Clear();
            }
            using (var sync = changesync.AcquireRead())
            {
                _hittest.MarkFirstInvalid(start);
                GameTrigger[] triggers = new GameTrigger[GameTrigger.TriggerTypes];
                for (int i = 0; i < count; i++)
                {
                    int currentframe = start + i;
                    var collisions   = new LinkedList <int>();
                    current.Rider = current.Rider.Simulate(
                        _savedcells,
                        bones,
                        collisions,
                        frameid: currentframe);
                    if (GetTriggersForFrame(triggers, currentframe))
                    {
                        var zoomtrigger = triggers[(int)TriggerType.Zoom];
                        if (zoomtrigger != null)
                        {
                            var delta = currentframe - zoomtrigger.Start;
                            zoomtrigger.ActivateZoom(delta, ref current.Zoom);
                        }

                        var bgtrigger = triggers[(int)TriggerType.BGChange];
                        if (bgtrigger != null)
                        {
                            var delta = currentframe - bgtrigger.Start;
                            Constants.StaticTriggerBGColor = _frames[start - 1].BGColor;
                            bgtrigger.ActivateBG(delta, currentframe, ref Constants.StaticTriggerBGColor, ref Constants.TriggerBGColor, ref current.BGColor);
                        }

                        var linetrigger = triggers[(int)TriggerType.LineColor];
                        if (linetrigger != null)
                        {
                            var delta = currentframe - linetrigger.Start;
                            Constants.StaticTriggerLineColorChange = _frames[start - 1].LineColor;
                            linetrigger.ActivateLine(delta, ref Constants.StaticTriggerLineColorChange, ref Constants.TriggerLineColorChange, currentframe, ref current.LineColor);
                        }
                    }
                    steps[i] = current;
                    collisionlist.Add(collisions);

                    // 10 seconds of frames,
                    // couldnt hurt to check?
                    if ((i + 1) % 400 == 0)
                    {
                        sync.ReleaseWaiting();
                    }
                }
                _hittest.AddFrames(collisionlist);
            }
            if (start + count > framecount)
            {
                _frames.EnsureCapacity(start + count);
                _frames.UnsafeSetCount(start + count);
            }
            for (int i = 0; i < steps.Length; i++)
            {
                _frames.unsafe_array[start + i] = steps[i];
            }
            FrameInvalidated?.Invoke(this, start);
        }