game-physics - Modulate the speed of the object in a while loop using delta time
问题描述
int i = 0;
void Car_Animation::update(float delta_time)
{
glm::tvec3<float> tar = { 0,0,0 };
tar = curve->curve_points_pos[(i+1) % (curve->points_pos.size())] -
curve->curve_points_pos[(i) % (curve->points_pos.size())];
m_model_mat = glm::translate(m_model_mat, tar);
i++;
}
The above function gets called in a while loop where delta_time is the difference between the previous frame and current frame;
while (!glfwWindowShouldClose(window))
{
animation->update(delta_time);
}
Right now, in the update
function, I am translating my model to a set of points in the curve->points_pos
. curve->points_pos
contains an array of points close to each other which gives an illusion of the model moving continuously.But the problem is, I want to modulate the speed of the model. How could I do it? I have delta_time
. Can I use that? I am using only glfw, glew and glm
, not using glut
.
解决方案
Correct me if I'm wrong, but it looks like you currently have:
* curve->curve_points_pos
, which is an array of locations that you want your model to pass through;
* m_model_mat
which is the current transformation matrix for your model; and
* i
, which is the current index into curve->curve_points_pos
.
The model then takes integral steps from one entry in curve->curve_points_pos
to the next, although you apply them as offsets from each other, rather than taking them as absolutes.
In that case what you basically have is a function of time, f(t)
evaluated at integral steps of t
and stored in curve->curve_points_pos
.
So, first: stop thinking in terms of updating m_model_mat
, and calculate it entirely per position. E.g.
m_model_mat = glm::translate(glm::mat4(1.f),
curve->curve_points_pos[(i) % (curve->points_pos.size())]);
If you have some other transform you also want to apply — e.g. if you want to move it away from the origin, compose that as an additional step.
Second: convert i
to a floating point number, and interpolate between entries in curve->curve_points_pos
. So:
const int i_integral = int(i) % curve->points_pos.size();
const int next_i_integral = int(i+1) % curve->points_pos.size();
const float i_fractional = fmodf(i, 1.f);
const auto curve_point =
curve->curve_points_pos[i_integral] * (1.f - i_fractional) +
curve->curve_points_pos[next_i_integral] * i_fractional;
m_model_mat = glm::translate(glm::mat4(1.f), curve_point);
There are a few bits to unpack there:
i
is now a floating point number, so it may describe a position between entries incurve->points_pos
;- I've assumed linearly interpolation (the model will walk a straight line between each pair of listed points), so:
- each position can be broken down into an integral part and a fractional part; where:
- the integral part identifies the two points the model is currently walking between — the integer itself will identify the one it has most recently departed from and, implicitly, it is walking towards whatever point comes next; and
- the fractional part identifies how far it has travelled between those two points, e.g. if the fractional part is .0 then the model hasn't actually left its origin yet, if it's .9999 then the model is very nearly at the next point, if it's .5 then the model is exactly halfway between the two, etc;
- the
curve_point
calculation then models that logic.
Aside observations:
- linear interpolation is not necessarily the best interpolation, but it's easy to understand and compute, and if your points are reasonably close together it is likely acceptable; but
- if your points are really close together, you might even be able to ditch interpolation all together, and just use the integral part as a direct point lookup. Then your model will warp from listed point to point after spending the correct amount of time at each, but if your points are very close together then that still may be acceptable.
推荐阅读
- javascript - 在字符串中查找特定字符并且不显示其余字符
- azure-ad-b2c - B2C 多语言问题,成功/失败消息以英文显示代替所选的 ui_locales 语言
- c# - 从 SP 读取多个 SELECT 返回的多个值
- nginx - Nginx 禁止 403
- node.js - Apollo Server Express - 无法到达游乐场
- android - 是否可以在颤动的应用栏中自定义抽屉符号?
- python - 使用 GitPython 返回给定根路径下的所有存储库
- reactjs - 如何将全局 scss 文件与 css-modules 一起使用?
- function - 如何修复“关闭:(动态)=> 函数'[函数]'中的无效:静态。” 在飞镖
- java - 将输入值添加到现有 Firebase 数据库值 Java?