最近看bullet,有源码就是看得明白点,有时候文档真的是无法说清的
就比如这个函数:
1 virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.));
非要看看源码才行的
默认情况下,最大执行步骤为1,固定步长为1/60,第一个参数为实际步长
这是一个放大的时间步长:0~2/60,物体在0时间为A状态,1/60为B状态,2/60为C状态
物体状态A 物体状态B 物体状态C
0----------------1/60--------------2/60
-timeStep
//在0~1/60以内,bullet并不执行物理模拟,剩余时间motionstate会进行进一步模拟 -timeStep
//在1/60~2/60以内,bullet执行一个物理模拟,bullet中物体处于B状态,但实际上物体应该还要在后面一个时间点,于是剩
余时间为总时间减去一个固定步长的时间,motionstate会根据这个剩余时间基于状态B进行进一步模拟
所谓进一步模拟 看代码 注意函数中的timeStep参数 该参数就是那个剩余时间:
1static void integrateTransform(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep,btTransform& predictedTransform)
2 {
3 predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep);
4// #define QUATERNION_DERIVATIVE
5 #ifdef QUATERNION_DERIVATIVE
6 btQuaternion predictedOrn = curTrans.getRotation();
7 predictedOrn += (angvel * predictedOrn) * (timeStep * btScalar(0.5));
8 predictedOrn.normalize();
9 #else
10 //Exponential map
11 //google for "Practical Parameterization of Rotations Using the Exponential Map", F. Sebastian Grassia
12
13 btVector3 axis;
14 btScalar fAngle = angvel.length();
15 //limit the angular motion
16 if (fAngle*timeStep > ANGULAR_MOTION_THRESHOLD)
17 {
18 fAngle = ANGULAR_MOTION_THRESHOLD / timeStep;
19 }
20
21 if ( fAngle < btScalar(0.001) )
22 {
23 // use Taylor's expansions of sync function
24 axis = angvel*( btScalar(0.5)*timeStep-(timeStep*timeStep*timeStep)*(btScalar(0.020833333333))*fAngle*fAngle );
25 }
26 else
27 {
28 // sync(fAngle) = sin(c*fAngle)/t
29 axis = angvel*( btSin(btScalar(0.5)*fAngle*timeStep)/fAngle );
30 }
31 btQuaternion dorn (axis.x(),axis.y(),axis.z(),btCos( fAngle*timeStep*btScalar(0.5) ));
32 btQuaternion orn0 = curTrans.getRotation();
33
34 btQuaternion predictedOrn = dorn * orn0;
35 predictedOrn.normalize();
36 #endif
37 predictedTransform.setRotation(predictedOrn);
38 } 所以,motionstate总是以插值的形态出现,代表物体的实际运动位置,可以用在实际游戏模拟中
靠,现在应该清楚的吧,如果还不清楚,请看源代码
到点了 请女人吃饭去了 附上相关代码:
1 int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
2 {
3 startProfiling(timeStep);
4
5 BT_PROFILE("stepSimulation");
6
7 int numSimulationSubSteps = 0;
8
9 if (maxSubSteps)
10 {
11 //fixed timestep with interpolation
12 m_localTime += timeStep;
13 if (m_localTime >= fixedTimeStep)
14 {
15 numSimulationSubSteps = int( m_localTime / fixedTimeStep);
16 m_localTime -= numSimulationSubSteps * fixedTimeStep;
17 }
18 } else
19 {
20 //variable timestep
21 fixedTimeStep = timeStep;
22 m_localTime = timeStep;
23 if (btFuzzyZero(timeStep))
24 {
25 numSimulationSubSteps = 0;
26 maxSubSteps = 0;
27 } else
28 {
29 numSimulationSubSteps = 1;
30 maxSubSteps = 1;
31 }
32 }
33
34 //process some debugging flags
35 if (getDebugDrawer())
36 {
37 btIDebugDraw* debugDrawer = getDebugDrawer ();
38 gDisableDeactivation = (debugDrawer->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
39 }
40 if (numSimulationSubSteps)
41 {
42
43 //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
44 int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps;
45
46 saveKinematicState(fixedTimeStep*clampedSimulationSteps);
47
48 applyGravity();
49
50
51
52 for (int i=0;i<clampedSimulationSteps;i++)
53 {
54 internalSingleStepSimulation(fixedTimeStep);
55 synchronizeMotionStates();
56 }
57
58 } else
59 {
60 synchronizeMotionStates();
61 }
62
63 clearForces();
64
65 #ifndef BT_NO_PROFILE
66 CProfileManager::Increment_Frame_Counter();
67 #endif //BT_NO_PROFILE
68
69 return numSimulationSubSteps;
70 }
71
72
posted on 2011-12-10 10:27
野猪红 阅读(2068)
评论(0) 编辑 收藏 引用 所属分类:
Bullet