Пример #1
0
        public void Handle(WorldClient client, MotionPacket packet)
        {
            var character = _gameWorld.Players[_gameSession.CharId];

            character.Motion = packet.Motion;

            _gameSession.StopLogOff();
        }
Пример #2
0
    void PostProcess()
    {
        if (samples.Count < 3)
        {
            return;
        }

        //compute velocity
        for (int i = 0; i < samples.Count; ++i)
        {
            int i1 = i + 1;
            if (i1 >= samples.Count)
            {
                i1 = i;
            }

            int i0 = i - 1;
            if (i0 < 0)
            {
                i0 = 0;
            }

            MotionPacket s0 = samples[i0];
            MotionPacket s  = samples[i];
            MotionPacket s1 = samples[i1];

            float dt = s1.time - s0.time;

            s.v     = (s1.centroid - s0.centroid) / dt;
            s.speed = s.v.magnitude;
            s.v_3   = Vector2ToVector3(s.v);

            if (s.speed > speedmost)
            {
                speedmost = s.speed;
            }
        }

        //compute acceleration
        for (int i = 0; i < samples.Count; ++i)
        {
            MotionPacket s0 = samples[i == 0?i:i - 1];
            MotionPacket s  = samples[i];
            MotionPacket s1 = samples[i == samples.Count - 1 ? i : i + 1];

            float dt = s1.time - s0.time;

            s.a    = (s1.v - s0.v) / dt;
            s.aMag = s.a.magnitude;
            s.a_3  = Vector2ToVector3(s.a);

            if (accmost < s.aMag)
            {
                accmost = s.aMag;
            }
        }
    }
        private void HandleMotion(MotionPacket packet)
        {
            if (packet.Motion == Motion.None || packet.Motion == Motion.Sit)
            {
                Motion = packet.Motion;
            }

            _logger.LogDebug($"Character {Id} sends motion {packet.Motion}");
            OnMotion?.Invoke(this, packet.Motion);
        }
Пример #4
0
    void resample()
    {
        float totaltime    = samples[samples.Count - 1].time;
        float TimeInterval = totaltime / 20.0f;

        for (float t = 0.0f; t < totaltime; t += TimeInterval)
        {
            MotionPacket m = evalAtTime(t);
            intsamples.Add(m);

            if (intsamples.Count > 1024)
            {
                intsamples.RemoveAt(0);
            }
        }
    }
Пример #5
0
    public MotionPacket evalAtTime(float t)
    {
        MotionPacket mp = new MotionPacket();

        if (samples.Count == 0)
        {
            return(mp);
        }
        mp = samples[0];
        MotionPacket p0, p1;

        if (t <= samples[0].time)
        {
            return(samples[0]);
        }
        if (t >= samples[samples.Count - 1].time)
        {
            return(samples[samples.Count - 1]);
        }

        for (int i = 0; i < samples.Count; ++i)
        {
            if (t <= samples[i].time)
            {
                p1 = samples[i];
                p0 = samples[i - 1];

                float nt = (t - p0.time) / (p1.time - p0.time);

                mp.centroid = p0.centroid * (1.0f - nt) + p1.centroid * nt;
                mp.speed    = p0.speed * (1.0f - nt) + p1.speed * nt;
                mp.aMag     = p0.aMag * (1.0f - nt) + p1.aMag * nt;
                mp.a        = p0.a * (1.0f - nt) + p1.a * nt;
                mp.v        = p0.v * (1.0f - nt) + p1.v * nt;
                mp.a_3      = p0.a_3 * (1.0f - nt) + p1.a_3 * nt;
                mp.v_3      = p0.v_3 * (1.0f - nt) + p1.v_3 * nt;
                mp.time     = t;
                return(mp);
            }
        }

        return(mp);
    }
Пример #6
0
    public void addSpeedTone(float t0, float t1, float f, MotionPacket m, float[] wave, int sampleRate_)
    {
        int i0 = (int)(t0 * sampleRate_);
        int i1 = (int)(t1 * sampleRate_);

        float   t              = t0;
        float   dt             = (t1 - t0) / (float)(i1 - i0);
        Vector3 xaxis          = new Vector3(1, 0, 0);
        float   coefficient    = -Vector3.Dot(m.v_3, xaxis) * 2 + 3.0f;
        float   ampcoefficient = m.centroid.y;


        float hz = f * 180 * Mathf.PI * 2.0f + 200.0f;

        for (int i = i0; i < i1 && i < wave.Length; ++i)
        {
            wave[i] += amp * ampcoefficient * Mathf.Sin(t * hz * coefficient);
            t       += dt;
        }
    }
Пример #7
0
    //void tone_vx(MotionPacket m, float dur, float[] wave, List<MotionPacket> motion)
    //{
    //    float t0 = motion[0].time;

    //    float startT = m.time - t0;
    //    float endT = startT + dur;


    //    addSinTone(startT, endT, 0.4f, 200.0f * (m.v.x + 1.0f), 0, wave, samplerate);


    //}

    //void tone_vy(MotionPacket m, float dur, float[] wave, List<MotionPacket> motion)
    //{
    //    float t0 = motion[0].time;

    //    float startT = m.time - t0;
    //    float endT = startT + dur;


    //    addSinTone(startT, endT, 0.4f, 200.0f * (m.v.y + 1.0f), 0, wave, samplerate);


    //}

    //void tone_cenx(MotionPacket m, float dur, float[] wave, List<MotionPacket> motion)
    //{
    //    float t0 = motion[0].time;
    //    float startT = m.time - t0;
    //    float endT = startT + dur;

    //    addSinTone(startT, endT, m.centroid.x, 200.0f, 0, wave, samplerate);
    //}

    //void tone_ceny(MotionPacket m, float dur, float[] wave, List<MotionPacket> motion)
    //{
    //    float t0 = motion[0].time;
    //    float startT = m.time - t0;
    //    float endT = startT + dur;

    //    addSinTone(startT, endT, m.centroid.y, 200.0f, 0, wave, samplerate);
    //}

    //void tone_ax(MotionPacket m, float dur, float[] wave, List<MotionPacket> motion)
    //{
    //    float t0 = motion[0].time;
    //    float startT = m.time - t0;
    //    float endT = startT + dur;

    //    addSinTone(startT, endT, 0.4f, 200.0f, m.a.x, wave, samplerate);
    //}

    //void tone_ay(MotionPacket m, float dur, float[] wave, List<MotionPacket> motion)
    //{
    //    float t0 = motion[0].time;
    //    float startT = m.time - t0;
    //    float endT = startT + dur;

    //    addSinTone(startT, endT, 0.4f, 200.0f, m.a.y, wave, samplerate);
    //}

    public void addTonePoint(MotionPacket m, float[] wave, List <MotionPacket> motion, float timescale)
    {
        float t0     = motion[0].time;
        float startT = (m.time - t0) * 3;
        float endT;


        if (m.aMag <= 1.0f)
        {
            dur = m.aMag * 0.2f;
        }
        else if (Mathf.Log(m.aMag) <= 4.0f)
        {
            dur = Mathf.Log(m.aMag) * 0.2f;
        }
        else
        {
            dur = 0.5f;
        }

        endT = startT + dur * timescale;

        addSpeedTone(startT, endT, m.speed, m, wave, samplerate);
    }
Пример #8
0
        public void InjestPacket(Packet p)
        {
            //Coaching
            //In order for this to happen, a few things must happen... (i will make the asssumption that the packets are UP TO DATE!)
            //This has to be a motion packet (this contains the X,Y, and Z position)
            //We have to already have seen the previous motion packet (this is used to see direction)
            //We have to already have seen the previous lap packet (this is used to see what sector we are in)
            if (p.PacketType == PacketType.Motion && LastReceivedPackets.Motion != null && LastReceivedPackets.Lap != null)
            {
                //Set up the variables that we will use
                MotionPacket  mp     = (MotionPacket)p;
                TrackLocation my_loc = new TrackLocation()
                {
                    PositionX = mp.FieldMotionData[mp.PlayerCarIndex].PositionX, PositionY = mp.FieldMotionData[mp.PlayerCarIndex].PositionY, PositionZ = mp.FieldMotionData[mp.PlayerCarIndex].PositionZ
                };

                if (Calibrating == true) //This is a new instance and we have to wait until the user gets to within a certain distancce of ANY corner to know what corner he is on
                {
                    //Find out what corner we are closest to
                    byte  nearest_corner          = 0;
                    float nearest_corner_distance = float.MaxValue;
                    for (int i = 0; i < LoadedTrackData.Corners.Length; i++) //Loop through each corner, measure the distance, and if this one is closest save it
                    {
                        TrackLocation tl = LoadedTrackData.Corners[i];
                        if (tl.Sector == LastReceivedPackets.Lap.FieldLapData[LastReceivedPackets.Lap.PlayerCarIndex].Sector) //We will only evaluate corners that are in the current sector we are in.
                        {
                            float this_distance = ApexVisualToolkit.DistanceBetweenTwoPoints(my_loc, tl);
                            if (this_distance < nearest_corner_distance)
                            {
                                nearest_corner_distance = this_distance;
                                nearest_corner          = (byte)(i + 1); //Plus one because we want the corner number, not the index of the corner.
                            }
                        }
                    }

                    //If the corner is within the threshold, mark this as an apex hit and mark the corner # we are on
                    if (nearest_corner_distance <= ApexDistanceThreshold)
                    {
                        AtCorner      = nearest_corner;
                        AtCornerStage = CornerStage.Apex;
                        Calibrating   = false; //We are no longer calibrating

                        //Invoke the events
                        try
                        {
                            CornerChanged.Invoke(nearest_corner);
                        }
                        catch
                        {
                        }
                        try
                        {
                            CornerStageChanged.Invoke(CornerStage.Apex);
                        }
                        catch
                        {
                        }
                    }
                }
                else //We are no longer calibrating
                {
                    if (AtCornerStage == CornerStage.Apex) //If the mode is currently "at apex", then wait until the user leaves the threshold and then mark it as "leaving"
                    {
                        //Measure the distance in between the car and that corner
                        TrackLocationOptima at_corner = LoadedTrackData.Corners[AtCorner - 1];
                        float distance_to_corner      = ApexVisualToolkit.DistanceBetweenTwoPoints(at_corner, my_loc);
                        if (distance_to_corner > ApexDistanceThreshold)
                        {
                            AtCornerStage = CornerStage.Exit;
                            try
                            {
                                CornerStageChanged.Invoke(CornerStage.Exit);
                            }
                            catch
                            {
                            }
                        }
                        else //If we are still inside the threshold, try to pinpoint if we are moving toward the apex or away from it. If we are move away from it (we have passed it), invoke the corner apex telemetry received received.
                        {
                            if (ApexTelemetryAlreadyBroadcastedForCurrentCorner == false) //We don't want to broadcast it twice, so we check to see if we already broadcasted it.
                            {
                                TrackLocation last_loc = new TrackLocation()
                                {
                                    PositionX = LastReceivedPackets.Motion.FieldMotionData[LastReceivedPackets.Motion.PlayerCarIndex].PositionX, PositionY = LastReceivedPackets.Motion.FieldMotionData[LastReceivedPackets.Motion.PlayerCarIndex].PositionY, PositionZ = LastReceivedPackets.Motion.FieldMotionData[LastReceivedPackets.Motion.PlayerCarIndex].PositionZ
                                };
                                float last_distance_to_corner = ApexVisualToolkit.DistanceBetweenTwoPoints(last_loc, at_corner);

                                //If this distance is GREATER THAN the last distance, it means we are moving away from it (we passed it). So trigger the telemetry
                                if (distance_to_corner >= last_distance_to_corner)
                                {
                                    try
                                    {
                                        ApexTelemetryReceived.Invoke(LastReceivedPackets.Telemetry.FieldTelemetryData[LastReceivedPackets.Telemetry.PlayerCarIndex], at_corner);
                                    }
                                    catch
                                    {
                                    }
                                    ApexTelemetryAlreadyBroadcastedForCurrentCorner = true; //Flip this to true so we dont broadcast it again in this corner. This will be flipped back to false once we leave this corner.
                                }
                            }
                        }
                    }
                    else if (AtCornerStage == CornerStage.Exit) //If We are in the corner exit: check if we are closer to the previous corner that we are exiting or the next corner. If we are closer to the next corner, flip it to entry for that corner.
                    {
                        //Get the previous corner index and the next corner index
                        int Previous_Corner_Index = AtCorner - 1;
                        int Next_Corner_Index;                          //This is a bit more complicated because if we are at the LAST corner of the lap, the next corner index would be 1!
                        if (AtCorner == LoadedTrackData.Corners.Length) //If the current corner is the LAST corner in the track data location
                        {
                            Next_Corner_Index = 0;
                        }
                        else
                        {
                            Next_Corner_Index = Previous_Corner_Index + 1;
                        }

                        //Get the previous and next corners
                        TrackLocation Previous_Corner = LoadedTrackData.Corners[Previous_Corner_Index]; //The current corner that we are exiting from (reduce by 1 for an index)
                        TrackLocation Next_Corner     = LoadedTrackData.Corners[Next_Corner_Index];     //The NEXT corner that we are now approaching.

                        //Check which one we are closer to
                        float distance_to_prev = ApexVisualToolkit.DistanceBetweenTwoPoints(Previous_Corner, my_loc);
                        float distance_to_next = ApexVisualToolkit.DistanceBetweenTwoPoints(Next_Corner, my_loc);

                        //If we are closer to next corner, flip it to that corner entry
                        if (distance_to_next <= distance_to_prev)
                        {
                            AtCorner      = (byte)(Next_Corner_Index + 1); //Flip the corner to the new corner
                            AtCornerStage = CornerStage.Entry;             //Set it to entry

                            //Raise the events
                            try
                            {
                                CornerChanged.Invoke((byte)(Next_Corner_Index + 1));
                            }
                            catch
                            {
                            }
                            try
                            {
                                CornerStageChanged.Invoke(CornerStage.Entry);
                            }
                            catch
                            {
                            }



                            //Flip the Already broadccasted telemetry for this apex corner to false
                            ApexTelemetryAlreadyBroadcastedForCurrentCorner = false;
                        }
                    }
                    else if (AtCornerStage == CornerStage.Entry) //If we are at the corner entry stage, check to see if we are within the threshold to call it an apex hit
                    {
                        //Get this corner
                        TrackLocation This_Corner = LoadedTrackData.Corners[AtCorner - 1];

                        //Measure the distance to that corner
                        float distance_to_corner = ApexVisualToolkit.DistanceBetweenTwoPoints(This_Corner, my_loc);

                        //If the distance is within the threshold, call it an apex hit
                        if (distance_to_corner <= ApexDistanceThreshold)
                        {
                            AtCornerStage = CornerStage.Apex;

                            //Raise the events
                            try
                            {
                                CornerStageChanged.Invoke(CornerStage.Apex);
                            }
                            catch
                            {
                            }
                        }
                    }
                }
            }



            #region "Save this packet"

            if (p.PacketType == PacketType.CarStatus)
            {
                LastReceivedPackets.CarStatus = (CarStatusPacket)p;
            }
            else if (p.PacketType == PacketType.Lap)
            {
                LastReceivedPackets.Lap = (LapPacket)p;
            }
            else if (p.PacketType == PacketType.Motion)
            {
                LastReceivedPackets.Motion = (MotionPacket)p;
            }
            else if (p.PacketType == PacketType.CarTelemetry)
            {
                LastReceivedPackets.Telemetry = (TelemetryPacket)p;
            }


            #endregion
        }
Пример #9
0
    void analysis()
    {
        Texture tex = videoScreen.mainTexture;

        Color[] cs = null;
        if (tex is RenderTexture)
        {
            RenderTexture rt = tex as RenderTexture;
            cs = getPixelsFromTexture(rt);
        }
        else if (tex is WebCamTexture)
        {
            WebCamTexture ct = tex as WebCamTexture;
            cs = ct.GetPixels();
        }
        else
        {
            return;
        }

        if (colorInPrev == null)
        {
            colorInPrev = cs;
        }
        else
        {
            colorInPrev = colorIn;
        }
        colorIn = cs;

        float cenx          = 0.0f;
        float ceny          = 0.0f;
        float totalMovement = 0.0f;
        int   k             = 0;

        for (int j = 0; j < h; ++j)
        {
            for (int i = 0; i < w; ++i)
            {
                float dr = colorIn[k].r - colorInPrev[k].r;
                float dg = colorIn[k].g - colorInPrev[k].g;
                float db = colorIn[k].b - colorInPrev[k].b;
                float dt = dr * dr + dg * dg + db * db;

                if (dt < dtThresh)
                {
                    dt = 0f;
                }

                totalMovement += dt;
                cenx          += i * dt;
                ceny          += j * dt;

                ++k;
            }
        }

        if (totalMovement > 0.001f)
        {
            cenx /= totalMovement;
            ceny /= totalMovement;
            cenx *= (1.0f / w);
            ceny *= (1.0f / w);
            Vector2 centroidNow = new Vector2(cenx, ceny);

            if (CenInPrev == null)
            {
                CenInPrev = centroidNow;
            }
            else
            {
                CenInPrev = Cen;
                Cen       = centroidNow;
            }

            //smoothening
            centroid = centroid * ratio + centroidNow * (1 - ratio);

            MotionPacket m = new MotionPacket();
            m.centroidInst = centroidNow;
            m.centroid     = centroid;
            m.totalM       = totalMovement;

            if (samples.Count == 0)
            {
                startRecTime = Time.time;
            }
            m.time = Time.time - startRecTime;
            samples.Add(m);

            if (samples.Count > 1024)
            {
                samples.RemoveAt(0);
            }
        }
    }