Archived

This topic is now archived and is closed to further replies.

Implementing Steady Motion

This topic is 5649 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

The movement of my objects seem to have a jerky appearance at times. At first I though that I was not using the performance timer, but this does not seem to be the case. I seem to be able to simulate the jerky mothion with the following code:
  
	}
	else if (lasttime == .003326f){
		lasttime =  .003907f;
	}
	else if (lasttime == .003907f){
		lasttime =  .008836f;
	}
	else if (lasttime == .008836f){
		lasttime =  .014549f;
	}
	else{
		lasttime = .042375f;
	}
	fTimeElapsed = lasttime;
  
PS: lasttime is a private variable that was created because efTimeElapsed was being passed to the function. Here is the code with the problem:
  
	m_vMove.x = (sin(m_fYaw) * m_fVelocity * fTimeElapsed);
	m_vMove.z = (cos(m_fYaw) * m_fVelocity * fTimeElapsed);

	char test[180];
	sprintf(test, "fTimeElapsed = %f  MoveX = %f  MoveZ = %f  Sin(m_fYaw) = %f  Cos(m_fYaw) = %f  m_fYaw = %f\n", fTimeElapsed,m_vMove.x, m_vMove.z,sin(m_fYaw),cos(m_fYaw), m_fYaw);
	OutputDebugString(test);

	m_vPosition.x = m_vPosition.x - m_vMove.x;
	m_vPosition.z = m_vPosition.z + m_vMove.z;
  
Here are the raw data vales:
  
fTimeElapsed = 0.008836  MoveX = 0.027366  MoveZ = -0.001190  Sin(m_fYaw) = 0.999056  Cos(m_fYaw) = -0.043437  m_fYaw = 1.614247
fTimeElapsed = 0.014549  MoveX = 0.045059  MoveZ = -0.001959  Sin(m_fYaw) = 0.999056  Cos(m_fYaw) = -0.043437  m_fYaw = 1.614247
fTimeElapsed = 0.042375  MoveX = 0.131239  MoveZ = -0.005706  Sin(m_fYaw) = 0.999056  Cos(m_fYaw) = -0.043437  m_fYaw = 1.614247
fTimeElapsed = 0.003326  MoveX = 0.010301  MoveZ = -0.000448  Sin(m_fYaw) = 0.999056  Cos(m_fYaw) = -0.043437  m_fYaw = 1.614247
fTimeElapsed = 0.003907  MoveX = 0.012100  MoveZ = -0.000526  Sin(m_fYaw) = 0.999056  Cos(m_fYaw) = -0.043437  m_fYaw = 1.614247
fTimeElapsed = 0.008836  MoveX = 0.027366  MoveZ = -0.001190  Sin(m_fYaw) = 0.999056  Cos(m_fYaw) = -0.043437  m_fYaw = 1.614247
fTimeElapsed = 0.014549  MoveX = 0.045059  MoveZ = -0.001959  Sin(m_fYaw) = 0.999056  Cos(m_fYaw) = -0.043437  m_fYaw = 1.614247
fTimeElapsed = 0.042375  MoveX = 0.131239  MoveZ = -0.005706  Sin(m_fYaw) = 0.999056  Cos(m_fYaw) = -0.043437  m_fYaw = 1.614247
fTimeElapsed = 0.003326  MoveX = 0.010301  MoveZ = -0.000448  Sin(m_fYaw) = 0.999056  Cos(m_fYaw) = -0.043437  m_fYaw = 1.614247
fTimeElapsed = 0.003907  MoveX = 0.012100  MoveZ = -0.000526  Sin(m_fYaw) = 0.999056  Cos(m_fYaw) = -0.043437  m_fYaw = 1.614247
fTimeElapsed = 0.008836  MoveX = 0.027366  MoveZ = -0.001190  Sin(m_fYaw) = 0.999056  Cos(m_fYaw) = -0.043437  m_fYaw = 1.614247
fTimeElapsed = 0.014549  MoveX = 0.045059  MoveZ = -0.001959  Sin(m_fYaw) = 0.999056  Cos(m_fYaw) = -0.043437  m_fYaw = 1.614247
fTimeElapsed = 0.042375  MoveX = 0.131239  MoveZ = -0.005706  Sin(m_fYaw) = 0.999056  Cos(m_fYaw) = -0.043437  m_fYaw = 1.614247
fTimeElapsed = 0.003326  MoveX = 0.010301  MoveZ = -0.000448  Sin(m_fYaw) = 0.999056  Cos(m_fYaw) = -0.043437  m_fYaw = 1.614247
fTimeElapsed = 0.003907  MoveX = 0.012100  MoveZ = -0.000526  Sin(m_fYaw) = 0.999056  Cos(m_fYaw) = -0.043437  m_fYaw = 1.614247
fTimeElapsed = 0.008836  MoveX = 0.027366  MoveZ = -0.001190  Sin(m_fYaw) = 0.999056  Cos(m_fYaw) = -0.043437  m_fYaw = 1.614247





  
In the event that I do have a timmer problem, and assuming that I would never see this numbers with the correct timer, I am using the m_fTimeElapsed from D3DAPP.CPP. Although, it seems that D3DAPP.CPP is actually getting it''s timer information from DXUTIL.CPP, and it is using the performance counter.

Share this post


Link to post
Share on other sites
One fix seems to be averaging the elapsed time over N number of frames. The following code averages the elapsed time over the entire duration. This would eventually overflow, but I could probably average over 20-60 frames with the same results. Is this something that is typical or should I be experiencing this problem?


    
dTotalTime += fTimeElapsed;
lTotalFrames++;
fTimeElapsed = dTotalTime/lTotalFrames;


[edited by - sdoherty55 on June 23, 2002 2:47:37 PM]

Share this post


Link to post
Share on other sites
Is this occuring because your framerate is jumping all over the place? It might be advantageous to see how/if you can stabilize the framerate.

If your framerate is the issue, then chances are that there are inefficiencies that you can clean up and that will affect your motion, neutralizing two avians with one mineral deposit.

Share this post


Link to post
Share on other sites
In windowed mode, the framerate is between 79 and 52 FPS. In full screen mode, the framerate is between 60 and 42 FPS.

Would you consider this to be an acceptable frame rate deviation?

PS: My system is a AMD 1800+, 512 megs of memory, Windows XP Pro, with a Retail ATI Radeon 64 Meg VIVO. The system scores 4000+ on 3DMark 2001 SE.

Share this post


Link to post
Share on other sites
I''m having the same problems he''s having. I haven''t looked into solutions for it yet because there are more important things I have to get to first in my code. But I''d love to hear anybody''s solution to the problem.

***********************
          

Share this post


Link to post
Share on other sites
Big Sassy,

Are you using D3DAPP.C for your performance timer or did you implement your own? Although, I don''t think that their should be a difference given it D3DAPP.C AND DXUTIL.C are using the QueryPerformanceCounter.

Averaging seems to work great, but it is not the correct solution.

Share this post


Link to post
Share on other sites
Looks like the issue effect most of the chipsets:

Currently, chips with the following PCI identifiers are known to exhibit a jump in performance counter value:

PCI ID Hardware Vendor
1039:0530 Silicon Integrated Systems (SiS)
1039:0620 Silicon Integrated Systems (SiS)
10B9:0533 Acer Labs, Inc. (ALi)
10B9:1533 Acer Labs, Inc. (ALi)
1106:0596 VIA Technologies, Inc. (VIA)
1106:0686 VIA Technologies, Inc. (VIA)
1166:004F Serverworks Corporation
1166:0050 Serverworks Corporation
8086:7110 Intel Corporation

This list will be updated as Microsoft observes the behavior in other chipsets.

Share this post


Link to post
Share on other sites
Ahhhhhhhhhhhh! timeGetTime() is awful, not sure if there is any Jerky motion, but the function is not very. Which means, if my code is correct, then most of the time there is actully no time difference?


      
fTimeGetTime = timeGetTime();
fTimeSpan = (fTimeGetTime-fLastTimeGetTime) * .001;
fLastTimeGetTime = fTimeGetTime;

if (fTimeSpan == 0){
return D3D_OK;
}



If I commend out the (if (fTimeSpan ==0), here is the data from the function. As you can see it only seems to return values of greater than 32 milliseconds.


        
TimeElapsed = 32.000000 MoveX = 85.265961 MoveZ = 50.698677 Sin(m_fYaw) = 0.859536 Cos(m_fYaw) = 0.511075 m_fYaw = 1.034361
fTimeElapsed = 0.000000 MoveX = 0.000000 MoveZ = 0.000000 Sin(m_fYaw) = 0.859536 Cos(m_fYaw) = 0.511075 m_fYaw = 1.034361
fTimeElapsed = 0.000000 MoveX = 0.000000 MoveZ = 0.000000 Sin(m_fYaw) = 0.859536 Cos(m_fYaw) = 0.511075 m_fYaw = 1.034361
fTimeElapsed = 0.000000 MoveX = 0.000000 MoveZ = 0.000000 Sin(m_fYaw) = 0.859536 Cos(m_fYaw) = 0.511075 m_fYaw = 1.034361
fTimeElapsed = 32.000000 MoveX = 85.265961 MoveZ = 50.698677 Sin(m_fYaw) = 0.859536 Cos(m_fYaw) = 0.511075 m_fYaw = 1.034361
fTimeElapsed = 0.000000 MoveX = 0.000000 MoveZ = 0.000000 Sin(m_fYaw) = 0.859536 Cos(m_fYaw) = 0.511075 m_fYaw = 1.034361
fTimeElapsed = 0.000000 MoveX = 0.000000 MoveZ = 0.000000 Sin(m_fYaw) = 0.859536 Cos(m_fYaw) = 0.511075 m_fYaw = 1.034361
fTimeElapsed = 0.000000 MoveX = 0.000000 MoveZ = 0.000000 Sin(m_fYaw) = 0.859536 Cos(m_fYaw) = 0.511075 m_fYaw = 1.034361
fTimeElapsed = 32.000000 MoveX = 85.265961 MoveZ = 50.698677 Sin(m_fYaw) = 0.859536 Cos(m_fYaw) = 0.511075 m_fYaw = 1.034361
fTimeElapsed = 0.000000 MoveX = 0.000000 MoveZ = 0.000000 Sin(m_fYaw) = 0.859536 Cos(m_fYaw) = 0.511075 m_fYaw = 1.034361
fTimeElapsed = 0.000000 MoveX = 0.000000 MoveZ = 0.000000 Sin(m_fYaw) = 0.859536 Cos(m_fYaw) = 0.511075 m_fYaw = 1.034361
fTimeElapsed = 0.000000 MoveX = 0.000000 MoveZ = 0.000000 Sin(m_fYaw) = 0.859536 Cos(m_fYaw) = 0.511075 m_fYaw = 1.034361
fTimeElapsed = 32.000000 MoveX = 85.265961 MoveZ = 50.698677 Sin(m_fYaw) = 0.859536 Cos(m_fYaw) = 0.511075 m_fYaw = 1.034361
fTimeElapsed = 0.000000 MoveX = 0.000000 MoveZ = 0.000000 Sin(m_fYaw) = 0.859536 Cos(m_fYaw) = 0.511075 m_fYaw = 1.034361
fTimeElapsed = 0.000000 MoveX = 0.000000 MoveZ = 0.000000 Sin(m_fYaw) = 0.859536 Cos(m_fYaw) = 0.511075 m_fYaw = 1.034361
fTimeElapsed = 0.000000 MoveX = 0.000000 MoveZ = 0.000000 Sin(m_fYaw) = 0.859536 Cos(m_fYaw) = 0.511075 m_fYaw = 1.034361


Maybe my code is wrong?



[edited by - sdoherty55 on June 23, 2002 5:24:19 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by sdoherty55
Maybe my code is wrong?


Yes, RTFM on timeBeginPeriod and timeEndPeriod.

[edited by - IndirectX on June 23, 2002 5:36:47 PM]

Share this post


Link to post
Share on other sites
"Yes, RTFM on timeBeginPeriod and timeEndPeriod."

I had actually already tried timeBeginePeriod, and the although there was nothing specific for XP in the manual. The manual did mention that Window2000/NT was likley to be set at 5 milliseconds. Looks like the problem with timeGetTime() was actually a loss of significance as a result of using floating point rather than double or DWORD.

Using timeGetTime does seem to fix the Jerky motion, it just is to bad that the performace counter does not seem to work; as the Microsoft MVP site actually does not recommend timeGetTime() in a tight loop.

For the record, my chipset is only a partial register match for the performance counter issue. Although, Microsoft does say that there is more chipsets to identify.

Thanks, CrazedGenius
Thanks, IndirectX; for the record I do read the manual.


[edited by - sdoherty55 on June 23, 2002 6:35:19 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by sdoherty55
Big Sassy,

Are you using D3DAPP.C for your performance timer or did you implement your own? Although, I don''t think that their should be a difference given it D3DAPP.C AND DXUTIL.C are using the QueryPerformanceCounter.

I use my own that uses QueryPerformanceCounter. IndirectX, that article sounds like that''s exactly what my problem is. I''m going to test it out in a sec and see if there is any difference. In any case, thanks for pointing out that article.

***********************
          

Share this post


Link to post
Share on other sites
Okey. I think I fixed the issue with the performance timer. I built a test project that uses timeGetTime, NeHe's QueryPerformanceCounter code, and my own timer class. I can't verify that it handles forward leaps well, because I cannot reliably get these leaps on my computer. I also included a text file with results of my counter on my computer.

Edit: please ignore comments if they don't make sense. Current timer class is a somewhat drastical redesign of the older timer I had, and I didn't put the comments in order yet.

[edited by - IndirectX on June 23, 2002 8:32:28 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
didn''t read all the posts, but maybe this could help..
http://www.mvps.org/directx/articles/implementing_steady_motion.htm

Share this post


Link to post
Share on other sites
IndirectX, I didn''t see your post until today. I will try your test program tonight and let you know.

Thanks for the Help.

AP, I actually already had the printouts from the Microsoft MVP site on you desk. That is a good site, full of information.

Share this post


Link to post
Share on other sites