Cubic Splines Revisited

Started by
2 comments, last by Tergiver 20 years, 1 month ago
In this thread Question(s) about cubic splines /*article*/ BauerGL had a problem getting his splines to work and his problem was solved. I have a different problem along the same lines. In BauerGL''s application, the client makes the assumption that it will get new entity state data at a regular interval. If a new state message has not come in, he simply uses the last known velocity and heading and applies it to the entity until a new packet does come in. In my application, the time between notifications of entity states is arbitrary. Because I may have hundreds or even thousands of entities, I''m sending periodic state data at very long intervals. If however, an entity changes states sooner than its due to send out, it sends that new state now. This means that I don''t have periodic state notification to base my splines on. What I thought I could do was this: Here is my Entity description minus a few details. The EntityState structure contains vPos and vVel (among other things).

struct Entity
{
	Entity* Next;

	EntityState esOld;
	EntityState esTarget;
	float fTimeLastUpdate;

	float A,B,C,D,E,F,G,H,I,J,K,L;

	void CalcCubicSpline(float fTimeNow)
	{
		float fTimeSpan = fTimeNow - fTimeLastUpdate;
		float fGap = fTimeSpan / 3.0f;

		D3DXVECTOR3 vPosT0 = esOld.vPos;
		D3DXVECTOR3 vPosT1 = esOld.vPos + esOld.vVel * fGap;
		D3DXVECTOR3 vPosT2 = esTarget.vPos - esTarget.vVel * fGap;
		D3DXVECTOR3 vPosT3 = esTarget.vPos;

		A = vPosT3.x - 3.0f * vPosT2.x + 3.0f * vPosT1.x - vPosT0.x;
		B = 3.0f * vPosT2.x - 6.0f * vPosT1.x + 3.0f * vPosT0.x;
		C = 3.0f * vPosT1.x - 3.0f * vPosT0.x;
		D = vPosT0.x;
		E = vPosT3.y - 3.0f * vPosT2.y + 3.0f * vPosT1.y - vPosT0.y;
		F = 3.0f * vPosT2.y - 6.0f * vPosT1.y + 3.0f * vPosT0.y;
		G = 3.0f * vPosT1.y - 3.0f * vPosT0.y;
		H = vPosT0.y;
		I = vPosT3.z - 3.0f * vPosT2.z + 3.0f * vPosT1.z - vPosT0.z;
		J = 3.0f * vPosT2.z - 6.0f * vPosT1.z + 3.0f * vPosT0.z;
		K = 3.0f * vPosT1.z - 3.0f * vPosT0.z;
		L = vPosT0.z;
	}

	D3DXVECTOR3 DeadReckon(float fTimeNow)
	{
		D3DXVECTOR3 _vPos;

		float fTime = fTimeNow - fTimeLastUpdate;
		float fTimeSq = fTime * fTime;
		float fTimeCb = fTimeSq * fTime;

		// At^3 + Bt^2 + Ct + D


		_vPos.x = A * fTimeCb + B * fTimeSq + C * fTime + D;
		_vPos.y = E * fTimeCb + F * fTimeSq + G * fTime + H;
		_vPos.z = I * fTimeCb + J * fTimeSq + K * fTime + L;
		return _vPos;
	}
};
Now when I get an entity state packet from the server, I process it on an entity state list class as follows:

void Update(EntityState* State, MyConnectSocket* pSock)
{
	//

	// If the entity is in the list, just update it


	for (Entity* Test = m_entityFirst; Test; Test = Test->Next)
	{
		if (Test->esOld.id == State->id)
		{
			memcpy(&Test->esOld, &Test->esTarget, sizeof(EntityState));
			Test->esOld.vPos = Test->DeadReckon(_fTimeThisFrame);
			memcpy(&Test->esTarget, State, sizeof(EntityState));
			Test->CalcCubicSpline(_fTimeThisFrame);
			Test->fTimeLastUpdate = _fTimeThisFrame;
			return;
		}
	}

	//

	// Not found, add it


	Test = new Entity;
	memcpy(&Test->esOld, State, sizeof(EntityState));
	memcpy(&Test->esTarget, State, sizeof(EntityState));
	Test->fTimeLastUpdate = _fTimeThisFrame;
	Test->Name[0] = 0;
	Test->CalcCubicSpline(_fTimeThisFrame);

	Test->Next = m_entityFirst;
	m_entityFirst = Test;
	m_Count++;

	pSock->BeginPacket(PPT_GET_ENTITY_INFO);
	pSock->WriteBuffer(&State->id, sizeof(State->id));
}
The idea is to generate a spline, have the entity follow it until either new data comes, or it reaches the end of the spline. If new data comes before it reaches the end, compute a new spline from where its at to the new end point. If it reaches the end before there is new data it has to just head off in the direction of the T4 vector. What I have so far (above) obviously doesn''t work. The problem I think I''m having is that while I can calculate the position the entity is at along the spline by calling DeadReckon, how do I get it''s velocity at that point to feed into a new CalcCubicSpline?
Advertisement
Describe its behavior. It''s still somewhat vague on how it''s failling. There are many possible issues with your scheme. If your going to do any preemptive scheme, you''ll need to send more state data.

Good Luck!

-ddn
Your right, that was pretty vague.
I''m really struggling with this thing alot and although I''ve gotten a better handle on it since I wrote that, I can''t elaborate any further at this point
I believe I got it worked out. Just in the tweeking state now.

This topic is closed to new replies.

Advertisement