This commit is contained in:
2025-11-24 14:19:51 +05:30
commit f5c1412b28
6734 changed files with 1527575 additions and 0 deletions

View File

@ -0,0 +1,150 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "slikenet/assert.h"
#include "slikenet/memoryoverride.h"
#include "TransformationHistory.h"
TransformationHistoryCell::TransformationHistoryCell()
{
}
TransformationHistoryCell::TransformationHistoryCell(SLNet::TimeMS t, const Ogre::Vector3& pos, const Ogre::Vector3& vel, const Ogre::Quaternion& quat ) :
time(t),
velocity(vel),
position(pos),
orientation(quat)
{
}
void TransformationHistory::Init(SLNet::TimeMS maxWriteInterval, SLNet::TimeMS maxHistoryTime)
{
writeInterval=maxWriteInterval;
maxHistoryLength = maxHistoryTime/maxWriteInterval+1;
history.ClearAndForceAllocation(maxHistoryLength+1, _FILE_AND_LINE_ );
RakAssert(writeInterval>0);
}
void TransformationHistory::Write(const Ogre::Vector3 &position, const Ogre::Vector3 &velocity, const Ogre::Quaternion &orientation, SLNet::TimeMS curTimeMS)
{
if (history.Size()==0)
{
history.Push(TransformationHistoryCell(curTimeMS,position,velocity,orientation), _FILE_AND_LINE_ );
}
else
{
const TransformationHistoryCell &lastCell = history.PeekTail();
if (curTimeMS-lastCell.time>=writeInterval)
{
history.Push(TransformationHistoryCell(curTimeMS,position,velocity,orientation), _FILE_AND_LINE_ );
if (history.Size()>maxHistoryLength)
history.Pop();
}
}
}
void TransformationHistory::Overwrite(const Ogre::Vector3 &position, const Ogre::Vector3 &velocity, const Ogre::Quaternion &orientation, SLNet::TimeMS when)
{
int historySize = history.Size();
if (historySize==0)
{
history.Push(TransformationHistoryCell(when,position,velocity,orientation), _FILE_AND_LINE_ );
}
else
{
// Find the history matching this time, and change the values.
int i;
for (i=historySize-1; i>=0; i--)
{
TransformationHistoryCell &cell = history[i];
if (when >= cell.time)
{
if (i==historySize-1 && when-cell.time>=writeInterval)
{
// Not an overwrite at all, but a new cell
history.Push(TransformationHistoryCell(when,position,velocity,orientation), _FILE_AND_LINE_ );
if (history.Size()>maxHistoryLength)
history.Pop();
return;
}
cell.time=when;
cell.position=position;
cell.velocity=velocity;
cell.orientation=orientation;
return;
}
}
}
}
TransformationHistory::ReadResult TransformationHistory::Read(Ogre::Vector3 *position, Ogre::Vector3 *velocity, Ogre::Quaternion *orientation,
SLNet::TimeMS when, SLNet::TimeMS curTime)
{
int historySize = history.Size();
if (historySize==0)
{
return VALUES_UNCHANGED;
}
int i;
for (i=historySize-1; i>=0; i--)
{
const TransformationHistoryCell &cell = history[i];
if (when >= cell.time)
{
if (i==historySize-1)
{
if (curTime<=cell.time)
return VALUES_UNCHANGED;
float divisor = (float)(curTime-cell.time);
RakAssert(divisor!=0.0f);
float lerp = (float)(when - cell.time) / divisor;
if (position)
*position=cell.position + (*position-cell.position) * lerp;
if (velocity)
*velocity=cell.velocity + (*velocity-cell.velocity) * lerp;
if (orientation)
*orientation = Ogre::Quaternion::Slerp(lerp, cell.orientation, *orientation,true);
}
else
{
const TransformationHistoryCell &nextCell = history[i+1];
float divisor = (float)(nextCell.time-cell.time);
RakAssert(divisor!=0.0f);
float lerp = (float)(when - cell.time) / divisor;
if (position)
*position=cell.position + (nextCell.position-cell.position) * lerp;
if (velocity)
*velocity=cell.velocity + (nextCell.velocity-cell.velocity) * lerp;
if (orientation)
*orientation = Ogre::Quaternion::Slerp(lerp, cell.orientation, nextCell.orientation,true);
}
return INTERPOLATED;
}
}
// Return the oldest one
const TransformationHistoryCell &cell = history.Peek();
if (position)
*position=cell.position;
if (orientation)
*orientation=cell.orientation;
if (velocity)
*velocity=cell.velocity;
return READ_OLDEST;
}
void TransformationHistory::Clear(void)
{
history.Clear(_FILE_AND_LINE_);
}