public void RegisterOrUpateRigidBody(Guid rigidBodyId, Guid sourceId)
        {
            if (!_sources.ContainsKey(sourceId))
            {
                _sources[sourceId] = new SnapshotBuffer(sourceId);
            }

            if (_rigidBodySourceMap.ContainsKey(rigidBodyId))
            {
                Guid oldSourceId = _rigidBodySourceMap[rigidBodyId];

                if (oldSourceId != sourceId)
                {
                    // Unregister from old source
                    _sources[oldSourceId].UnregisterRigidBody(rigidBodyId);

                    // Register for new source
                    _sources[sourceId].RegisterRigidBody(rigidBodyId);
                    _rigidBodySourceMap[rigidBodyId] = sourceId;
                }
            }
            else
            {
                // Register for appropriate source
                _sources[sourceId].RegisterRigidBody(rigidBodyId);
                _rigidBodySourceMap[rigidBodyId] = sourceId;
            }
        }
示例#2
0
            public void step(float timestep)
            {
                if (_mode == Mode.Init)
                {
                    // todo: do we need this warm up?
                    if (SnapshotBuffer.Snapshots.Count >= 4)
                    {
                        _mode = Mode.Play;

                        CurrentSnapshot  = SnapshotBuffer.Snapshots.First().Value;
                        CurrentLocalTime = CurrentSnapshot.Time;
                    }
                }
                else if (_mode != Mode.Init)
                {
                    // todo: consider exposing as a parameter or calculating based on local and remote timesteps.
                    const float bufferTimeBiasTimeUnit = 1.0f / 60;

                    float targetBufferTime       = _stats.mean() - _stats.deviation();
                    float biasedTargetBufferTime = targetBufferTime / bufferTimeBiasTimeUnit;

                    biasedTargetBufferTime = biasedTargetBufferTime > 0 ?
                                             ((int)biasedTargetBufferTime) * bufferTimeBiasTimeUnit : ((int)biasedTargetBufferTime - 1) * bufferTimeBiasTimeUnit;

                    float nextTimestamp = CurrentLocalTime + timestep;
                    float bufferedTime  = SnapshotBuffer.Snapshots.Last().Value.Time - nextTimestamp;

                    _stats.addSample(bufferedTime);

                    // check if time shift is required
                    float timeShift;
                    if (Math.Abs(biasedTargetBufferTime) > 0.001)
                    {
                        // todo: limit slow-down, don't allow time to move to the past
                        timeShift = biasedTargetBufferTime > 0 ?
                                    _speedUpCoef * biasedTargetBufferTime : _speedDownCoef * biasedTargetBufferTime;

                        nextTimestamp += timeShift;
                        _stats.shiftTime(-timeShift);
                    }
                    else
                    {
                        timeShift = 0;
                    }

#if DEBUG_JITTER_BUFFER
                    _debugStats.add(bufferedTime, _stats.mean(), targetBufferTime, biasedTargetBufferTime, timeShift, nextTimestamp);
#endif

                    if (nextTimestamp <= SnapshotBuffer.Snapshots.Last().Value.Time)
                    {
                        // Snapshot can be interpolated from the buffers
                        HasUpdate = true;

                        Snapshot prev, next;
                        SnapshotBuffer.step(nextTimestamp, out prev, out next);

                        if (Math.Abs(next.Time - nextTimestamp) < 0.001)
                        {
                            // if offset is less than a millisecond, just use 'next' snapshot time
                            CurrentLocalTime = next.Time;
                            CurrentSnapshot  = next;
                        }
                        else if (prev != null)
                        {
                            if (Math.Abs(prev.Time - nextTimestamp) < 0.001)
                            {
                                // if offset is less than a millisecond, just use 'prev' snapshot time
                                CurrentLocalTime = prev.Time;
                                CurrentSnapshot  = prev;
                            }
                            else
                            {
                                float frac = (nextTimestamp - prev.Time) / (next.Time - prev.Time);

                                List <Snapshot.TransformInfo> transforms = new List <Snapshot.TransformInfo>(next.Transforms.Count);

                                int prevIndex = 0;
                                int nextIndex = 0;

                                for (; nextIndex < next.Transforms.Count; nextIndex++)
                                {
                                    // find corresponding transform in prev snapshot
                                    while (prevIndex < prev.Transforms.Count && prev.Transforms[prevIndex].Id.CompareTo(next.Transforms[nextIndex].Id) < 0)
                                    {
                                        prevIndex++;
                                    }

                                    if (prevIndex < prev.Transforms.Count &&
                                        prev.Transforms[prevIndex].Id == next.Transforms[nextIndex].Id)
                                    {
                                        RigidBodyTransform t = new RigidBodyTransform();
                                        {
                                            t.Lerp(prev.Transforms[prevIndex].Transform, next.Transforms[nextIndex].Transform, frac);
                                        }

                                        transforms.Add(new Snapshot.TransformInfo(next.Transforms[nextIndex].Id, t,
                                                                                  next.Transforms[nextIndex].motionType));
                                    }
                                    else
                                    {
                                        transforms.Add(new Snapshot.TransformInfo(next.Transforms[nextIndex].Id,
                                                                                  next.Transforms[nextIndex].Transform, next.Transforms[nextIndex].motionType));
                                    }
                                }

                                // interpolated snapshot
                                CurrentLocalTime = nextTimestamp;
                                CurrentSnapshot  = new Snapshot(nextTimestamp, transforms);
                            }
                        }
                        else
                        {
                            // if prev snapshot is missing, just use current transforms with past timestamp
                            CurrentLocalTime = nextTimestamp;
                            CurrentSnapshot  = next;
                        }
                    }
                    else
                    {
                        // Snapshot can not be interpolated from the buffers
                        HasUpdate = false;

                        CurrentLocalTime = nextTimestamp;
                        CurrentSnapshot  = new Snapshot(CurrentLocalTime, CurrentSnapshot.Transforms);
                    }
                }
            }
示例#3
0
 public void addSnapshot(Snapshot snapshot)
 {
     SnapshotBuffer.addSnapshot(snapshot);
 }