Advertisement

Cubic Splines for use in Dead Reckoning

Started by June 15, 2003 11:14 PM
6 comments, last by DirectXFreak 21 years, 7 months ago
Hi, I''m making a real time 3d (uses only x and z coordinates though) multiplayer hover tank game using C++ and directplay... I need to know how to IMPLIMENT cubic splines. I''ve read the gamedev article on it, now i just need to know how to code it. If someone could please show me some code then i would be eternally gratefull...
--m_nPostCount++
Could someone check my code?
The ship jitters and pops when i use it, here it is:


// The actual math, tell me if its wrong
float D3DTankArena::fBuildSpline( float fOld,float fVelOld,float fVelNew,float fNew,float t ) {
float v0= fOld;
float v1= v0 + fVelOld;
float v2= fNew + fVelNew * t + 0.5f * 0.0f * (t*t);
float v3= fNew;

float a1= 3.0f * v2;
float b1= 3.0f * v1;
float c1= 6.0f * v1;
float d1= 3.0f * v0;

float a2 = v3 - a1 + b1 - v0;
float b2 = a1 - c1 + d1;
float c2 = b1 - d1;
float d2 = v0;

return(a2*(t*t*t) + b2*(t*t) + c2*t + d2);
}

// This gets called in the main loop every frame...
HRESULT D3DTankArena::hrUpdateNetwork()
{
void *packet;
int i=0;

for( i=0;i if( m_pPlayerInfo.dpnidPlayer != m_dpnidLocalPlayer )
if( m_pPlayerInfo.bActive ) {<br> break;<br> }<br> }<br><br><br> if( (timeGetTime()-m_dwUpdateTimer)>300 ) <br> {<br> if( m_lNumberOfActivePlayers > 1 ) <br> {<br> m_pPlayerInfo.vOldPos = m_pPlayerInfo.vNewPos;<br> m_pPlayerInfo.fLastVelX = m_pPlayerInfo.fNewVelX;<br> m_pPlayerInfo.fLastVelZ = m_pPlayerInfo.fNewVelZ;<br> m_pPlayerInfo.fLastVelX = m_pPlayerInfo.fNewVelX;<br> m_pPlayerInfo.fLastVelZ = m_pPlayerInfo.fNewVelZ;<br><br> m_pPlayerInfo.vNewPos = m_vNewSyncPos;<br> m_pPlayerInfo.fNewVelX = m_vNewSyncVel.x;<br> m_pPlayerInfo.fNewVelZ = m_vNewSyncVel.y;<br> }<br> m_dwUpdateTimer = timeGetTime();<br> }<br><br> if( timeGetTime() > m_dwUpdateTimer+150 ) { <br> m_pSyncMsg.vPos = D3DXVECTOR2( m_pPlayerInfo[m_iLocalPlayerId].vPosition.x,m_pPlayerInfo[m_iLocalPlayerId].vPosition.z );<br> m_pSyncMsg.vVel = D3DXVECTOR2( m_pPlayerInfo[m_iLocalPlayerId].fVelX,m_pPlayerInfo[m_iLocalPlayerId].fVelZ );<br> m_pSyncMsg.fAngle = m_pPlayerInfo[m_iLocalPlayerId].fRot;<br> packet = (VOID*)&m_pSyncMsg;<br> hrSendPeerMessage( -1,PACKET_TYPE_SYNC,packet );<br> }<br> <br> if( i != MAX_PLAYERS ) {<br> float t=(float)( (float)timeGetTime()-m_dwUpdateTimer )/(float)300.0f;<br> m_pPlayerInfo.vPosition.x = fBuildSpline( m_pPlayerInfo.vOldPos.x,m_pPlayerInfo.fLastVelX,m_pPlayerInfo.fNewVelX,m_pPlayerInfo.vNewPos.x,t );<br> m_pPlayerInfo.vPosition.z = fBuildSpline( m_pPlayerInfo.vOldPos.z,m_pPlayerInfo.fLastVelZ,m_pPlayerInfo.fNewVelZ,m_pPlayerInfo.vNewPos.z,t ); <br> }<br><br> return S_OK;<br>}<br><br>// this code is taken out of the directplay message handler…<br> case PACKET_TYPE_SYNC:<br> {<br> iPlayerId = iGetPlayerId( pReceiveMsg->dpnidSender );<br> pSync = (PacketSync*)pReceiveMsg->pReceiveData;<br> <br> m_vNewSyncPos.x = pSync->vPos.x;<br> m_vNewSyncPos.z = pSync->vPos.y;<br> m_vNewSyncVel = pSync->vVel;<br><br> break;<br> }<br><br>Please help, the ship follows the path, but it jitter back and forth quickly, thanks a ton! </i>
--m_nPostCount++
Advertisement
Hi!
Sorry, I haven''t check your code.
I had the same problems with the cubic splines and now can tell why.
That article about cubic splines sucks.
You can use cubic splines only for INTERPOLATION, and what you need for network code is EXTRAPOLATION.
When the cubic curve you''ve built may be used only between control points, i.e. only for interpolation. Outside [0,1] region cubic spline behaves very bad -> you feel jitter.
The answer is in quadratic curves. Some easy math and you''re happy:
p = A*t^2 + B*t + C;
v = 2*A*t + B;

t0: p0, v0
t1: p1, v1

exact formulas left as an exercise to the reader


Best regards,
Dmitry S. Baikov
Best regards,Dmitry S. Baikov
soooo, p will be the position, and v the velocity?

one other question...

the A, B and C variables are declared like this correct?

A = x3 – 3x2 +3x1 – x0
B = 3x2 – 6x1 + 3x0
C = 3x1 – 3x0

oh and by the way...
what does this mean exactly?

t0: p0, v0
t1: p1, v1

thank you very much
--m_nPostCount++
it doesn't work, please check my code....

float D3DTankArena::fBuildSpline( float fOld,float fVelOld,float fVelNew,float fNew,float t ) {
float v0= fOld;
float v1= v0 + fVelOld;
float v2= fNew + (fVelNew * t) + (0.5f * 0.05f) * (t*t);
float v3= fNew;
/*
float a1= 3.0f * v2;
float b1= 3.0f * v1;
float c1= 6.0f * v1;
float d1= 3.0f * v0;

float a2 = v3 - a1 + b1 - v0;
float b2 = a1 - c1 + d1;
float c2 = b1 - d1;
float d2 = v0;

return(a2*(t*t*t) + b2*(t*t) + c2*t + d2);*/

float A = v3 - (3.0f*v2) + (3.0f*v1) - v0;
float B = (3.0f*v2) - (6.0f*v1) + (3.0f*v0);
float C = (3.0f*v1) - (3.0f*v0);

float p = (A*(t*t)) + (B*t) + C;
float v = (2.0f*A*t) + B;

return(p+v);
}


HRESULT D3DTankArena::hrUpdateNetwork()
{
void *packet;
int i=0;


////////////////////////////////////////////////////////////
//
// Dead Reckoning stuff...
//
////////////////////////////////////////////////////////////
for( i=0;i if( m_pPlayerInfo.dpnidPlayer != m_dpnidLocalPlayer )
if( m_pPlayerInfo.bActive ) {<br> break;<br> }<br> }<br><br><br> if( (timeGetTime()-m_dwUpdateTimer)>300 ) <br> {<br> if( m_lNumberOfActivePlayers > 1 ) <br> {<br> m_pPlayerInfo.vOldPos = m_pPlayerInfo.vNewPos;<br> m_pPlayerInfo.fLastVelX = m_pPlayerInfo.fNewVelX;<br> m_pPlayerInfo.fLastVelZ = m_pPlayerInfo.fNewVelZ;<br> m_pPlayerInfo.fLastVelX = m_pPlayerInfo.fNewVelX;<br> m_pPlayerInfo.fLastVelZ = m_pPlayerInfo.fNewVelZ;<br><br> m_pPlayerInfo.vNewPos = m_vNewSyncPos;<br> m_pPlayerInfo.fNewVelX = m_vNewSyncVel.x;<br> m_pPlayerInfo.fNewVelZ = m_vNewSyncVel.y;<br> }<br> m_dwUpdateTimer = timeGetTime();<br> }<br><br> if( timeGetTime() > m_dwUpdateTimer+150 ) { <br> m_pSyncMsg.vPos = D3DXVECTOR2( m_pPlayerInfo[m_iLocalPlayerId].vPosition.x,m_pPlayerInfo[m_iLocalPlayerId].vPosition.z );<br> m_pSyncMsg.vVel = D3DXVECTOR2( m_pPlayerInfo[m_iLocalPlayerId].fVelX,m_pPlayerInfo[m_iLocalPlayerId].fVelZ );<br> m_pSyncMsg.fAngle = m_pPlayerInfo[m_iLocalPlayerId].fRot;<br> packet = (VOID*)&m_pSyncMsg;<br> hrSendPeerMessage( -1,PACKET_TYPE_SYNC,packet );<br> }<br> <br> if( i != MAX_PLAYERS ) {<br> float t=(float)( (float)timeGetTime()-m_dwUpdateTimer )/(float)300.0f;<br> m_pPlayerInfo.vPosition.x = fBuildSpline( m_pPlayerInfo.vOldPos.x,m_pPlayerInfo.fLastVelX,m_pPlayerInfo.fNewVelX,m_pPlayerInfo.vNewPos.x,t );<br> m_pPlayerInfo.vPosition.z = fBuildSpline( m_pPlayerInfo.vOldPos.z,m_pPlayerInfo.fLastVelZ,m_pPlayerInfo.fNewVelZ,m_pPlayerInfo.vNewPos.z,t ); <br> }<br><br> return S_OK;<br>}<br> </i> <br><br>oh, and my ultimate question…<br><br>what do i do with p and v (i assume position and velocity)?<br>add them together and update the players position like this?<br><br>m_pPlayerInfo<i>.vPosition = p+v;<br><br><SPAN CLASS=editedby>[edited by - DirectXFreak &#111;n June 18, 2003 7:59:09 PM]</SPAN> </i>
--m_nPostCount++
cOff! please help... I need some help!!!!!
--m_nPostCount++
Advertisement
http://www.gamasutra.com/features/19970919/aronson_01.htm
Game Programming Gems II
Please, anybody, could you just give me a better discription of cOff''s post... Please....
--m_nPostCount++

This topic is closed to new replies.

Advertisement