<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-gb">
	<link rel="self" type="application/atom+xml" href="https://pybullet.org/Bullet/phpBB3/app.php/feed/topic/9463" />

	<title>Real-Time Physics Simulation Forum</title>
	
	<link href="https://pybullet.org/Bullet/phpBB3/index.php" />
	<updated>2013-10-06T19:02:49+00:00</updated>

	<author><name><![CDATA[Real-Time Physics Simulation Forum]]></name></author>
	<id>https://pybullet.org/Bullet/phpBB3/app.php/feed/topic/9463</id>

		<entry>
		<author><name><![CDATA[theagentd]]></name></author>
		<updated>2013-10-06T19:02:49+00:00</updated>

		<published>2013-10-06T19:02:49+00:00</published>
		<id>https://pybullet.org/Bullet/phpBB3/viewtopic.php?p=31900#p31900</id>
		<link href="https://pybullet.org/Bullet/phpBB3/viewtopic.php?p=31900#p31900"/>
		<title type="html"><![CDATA[Bullet is extrapolating, not interpolating + other bug+fix]]></title>

		
		<content type="html" xml:base="https://pybullet.org/Bullet/phpBB3/viewtopic.php?p=31900#p31900"><![CDATA[
I'm getting visible snapping whenever the velocity of a body is changed.<br><br>I have a simple test program in which I have a sphere falling due to gravity. I'm running at a fixed time step of 1/2f (to exaggerate the problem), and I'm updating at 1/32f intervals, which results in 16 interpolated positions for each real internal step. After every tick there is a huge snap caused by Bullet extrapolating, which is not accurate when velocity changes. Each call to stepSimulation() I print out the difference in Y-position of the interpolated transform. Here's the output: <a href="http://pastie.org/8382173" class="postlink">http://pastie.org/8382173</a><br><br>After each tick, the position has to be corrected since the predicted collision was not correct due to gravity. The problem lies in btTransformUtil.h: <a href="https://code.google.com/p/bullet/source/browse/tags/bullet-2.81/src/LinearMath/btTransformUtil.h" class="postlink">https://code.google.com/p/bullet/source ... formUtil.h</a> The first line:<div class="codebox"><p>Code: </p><pre><code>predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep);</code></pre></div>This is the complete opposite of interpolation; it's extrapolation. Either the Wiki is completely misguiding, or this code is not doing what it's supposed to.<br><br>Related: <a href="http://liquidrockgames.blogspot.se/2009/03/smoothness-and-frame-rate-independent.html" class="postlink">http://liquidrockgames.blogspot.se/2009 ... ndent.html</a><br><br><br>EDIT 1:<br><br>On top of this, running Bullet without extrapolation (world.stepSimulation(timeStep, 0);) will cause the transform given to MotionState.setWorldTransform() to still be extrapolated.<br><br>Here's an example flow of my program:<br><div class="codebox"><p>Code: </p><pre><code>Game loop iteration start.world.stepSimulation(timestep, 0); called.Tick callback received. In here I also modify the velocity manually, which would screw up the extrapolation. Y is not modified however, so that is not the problem seen here.Transform updated by Bullet through MotionState.setWorldTransform().world.stepSimulation() returns.Starting render procedure.Position from btRigidBody.getWorldTransform():[1.0|0.0|0.0|0.9941138][0.0|1.0|0.0|6.691561][0.0|0.0|1.0|0.97757304][0.0|0.0|0.0|1.0]Position set earlier by Bullet from MotionState.setWorldTransform():[1.0|0.0|0.0|0.9941138][0.0|1.0|0.0|5.476966][0.0|0.0|1.0|0.97757304][0.0|0.0|0.0|1.0]Render procedure returns.End of game loop iteration.</code></pre></div>The ground level here is at 7.5. Notice how exaggerated the natural tunneling is in the extrapolated transform from MotionState.setWorldTransform(). The next update/frame however gives identical positions for both methods since now the velocity is 0 after it has hit the ground:<div class="codebox"><p>Code: </p><pre><code>Position from btRigidBody.getWorldTransform():[1.0|0.0|0.0|0.9941138][0.0|1.0|0.0|7.338312][0.0|0.0|1.0|0.97757304][0.0|0.0|0.0|1.0]Position set earlier by Bullet from MotionState.setWorldTransform():[1.0|0.0|0.0|0.9941138][0.0|1.0|0.0|7.338312][0.0|0.0|1.0|0.97757304][0.0|0.0|0.0|1.0]</code></pre></div><br>Am I missing something here? Bullet seems to be causing unnecessary amounts of tunneling regardless of if extrapolation is supposed to be enabled or not! <img class="smilies" src="https://pybullet.org/Bullet/phpBB3/images/smilies/icon_sad.gif" width="15" height="15" alt=":(" title="Sad"> I would be very happy if someone could try to reproduce this!<br><br><br>EDIT 2:<br>Further testing confirmed that world.stepSimulation(timestep, 0) extrapolates exactly &lt;timestep&gt; seconds ahead into the unknown future when updating MotionStates through setWorldTransform():<div class="codebox"><p>Code: </p><pre><code>Update time step: 0.12501013Body velocity: 10.0btRigidBody getWorldTransform() Y translation: 36.244843btMotionState setWorldTransform() Y translation: 37.494946Difference: 1.250103 which is almost exactly &lt;velocity&gt; * &lt;time step&gt;.</code></pre></div>This is caused in <a href="https://code.google.com/p/bullet/source/browse/tags/bullet-2.81/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp" class="postlink">https://code.google.com/p/bullet/source ... sWorld.cpp</a> on line 416:<div class="codebox"><p>Code: </p><pre><code>m_localTime = timeStep;</code></pre></div>Later, m_localTime is passed into the extrapolation function on line 361 in the same file. m_localTime is only used for extrapolation, so simply replacing the above code with<div class="codebox"><p>Code: </p><pre><code>m_localTime = 0;</code></pre></div>would solve this problem for variable time steps (but not do anything for my original problem).<br><br><br>EDIT 3:<br>My brain isn't going to let me sleep, so I might as well... After seeing the code, I realized that it may be possible to very easily turn the extrapolation into interpolation for fixed time steps by simply modifying the m_localTime variable. Currently m_localTime ranges from 0 (current frame) to fixedTimeStep (1 step into the unknown future). By simply subtracting fixedTimeStep from m_localTime when passing in that value for integration on line 361 the range would go from -fixedTimeStep (1 step into the past) to 0 instead. This would require a few simple changes to be implemented:<br>1. fixedTimeStep needs to be saved to a local variable in stepSimulation(), say m_fixedTimeStep.<br>2. a boolean variable has to be added for switching between interpolation and extrapolation is needed. It also needs a getter and a setter.<br>3. synchronizeSingleMotionState() should check the mentioned boolean variable, and pass in (m_localTime - m_fixedTime) instead of (m_localTime * body-&gt;getHitFraction()) if interpolation is enabled. I'm not 100% sure, but I don't think the hit fraction has to be taken into consideration when interpolating.<p>Statistics: Posted by <a href="https://pybullet.org/Bullet/phpBB3/memberlist.php?mode=viewprofile&amp;u=10487">theagentd</a> — Sun Oct 06, 2013 7:02 pm</p><hr />
]]></content>
	</entry>
	</feed>
