Skip to content

Commit 6a88082

Browse files
authored
Added interpolation example. (#148)
* Added interpolation example. * Changed rotation to use vectors instead of quaternions. Fixed getting config number. Fixed game.project settings and updated manual.
1 parent 89696d2 commit 6a88082

14 files changed

Lines changed: 475 additions & 0 deletions
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
path_settings {
2+
path: "**"
3+
profile: "Default"
4+
}
5+
profiles {
6+
name: "Default"
7+
platforms {
8+
os: OS_ID_GENERIC
9+
formats {
10+
format: TEXTURE_FORMAT_RGBA
11+
compression_level: BEST
12+
compression_type: COMPRESSION_TYPE_DEFAULT
13+
}
14+
mipmaps: false
15+
max_texture_size: 0
16+
premultiply_alpha: true
17+
}
18+
}
146 KB
Binary file not shown.
822 Bytes
Loading
1.01 KB
Loading
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
images {
2+
image: "/assets/elementStone019.png"
3+
}
4+
images {
5+
image: "/assets/elementStone023.png"
6+
}
7+
extrude_borders: 2
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
font: "/assets/SourceSansPro-Semibold.ttf"
2+
material: "/builtins/fonts/font.material"
3+
size: 64
4+
characters: " !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"

physics/interpolation/engine.png

23.2 KB
Loading

physics/interpolation/example.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
tags: physics
3+
title: Fixed timestep interpolation
4+
brief: This example shows how to smooth physics motion in fixed update mode by interpolating a visual sprite while keeping the physics body fixed-step.
5+
author: Defold Foundation
6+
scripts: interpolation.script
7+
thumbnail: thumbnail.png
8+
---
9+
10+
This example demonstrates two rendering paths while physics runs at a fixed frequency:
11+
- `Not interpolated`: visual sprite follows the dynamic body directly (visually looks like it has a stepped motion).
12+
- `Interpolated`: visual sprite is interpolated between fixed physics states (smooth motion).
13+
14+
The key idea is to separate physics simulation from rendering:
15+
- Keep the transforms of the game objects with dynamic collision objects as the source of truth.
16+
- Set position of the visual representation based on the position of the physics objects.
17+
- Interpolate only the visual representation transform.
18+
19+
## Setup
20+
21+
In `game.project`:
22+
1. In the `Physics` section set `Use_Fixed_Timestep` enabled and `Velocity Threshold` to 50 (It is necessary for 2D physics, because velocity threshold is scaled with the scale option, and in the end it should be 1.0 internally in Box2D, so if Scale is set to 0.02, the velocity threshold should be 50 = 1.0 / 0.02). Gravity is set arbitraly for this example to -500.
23+
24+
![physics](physics.png)
25+
26+
2. In the `Engine` section set `Fixed Update Frequency` to a low value, e.g. 20, so the difference is easy to see.
27+
28+
![engine](engine.png)
29+
30+
31+
The setup consists of 5 game objects:
32+
33+
![setup](setup.png)
34+
35+
`walls`
36+
: Static borders and the script host.
37+
- A static *Collision object* component.
38+
- A script component using `/example/interpolation.script`.
39+
40+
`block1`
41+
: Game Object for the non-interpolated path for the physics component.
42+
- A dynamic *Collision object* component.
43+
- No sprite (physics-only object).
44+
45+
`block1_sprite`
46+
: Game Object for the non-interpolated path for the visual representation.
47+
- A *Sprite* component.
48+
- A *Label* component (with text `Not interpolated`).
49+
50+
`block2`
51+
: Game Object for the interpolated path for the physics component.
52+
- A dynamic *Collision object* component.
53+
- No sprite (physics-only object).
54+
55+
`block2_sprite`
56+
: Game Object for the non-interpolated path for the visual representation.
57+
- A *Sprite* component.
58+
- A *Label* component (with text `Interpolated`).
59+
60+
## Script Behavior
61+
62+
`/example/interpolation.script`:
63+
1. Keeps a two-sample fixed-state buffer for `block2`:
64+
- `previous` = previous fixed physics sample
65+
- `current` = current fixed physics sample
66+
2. In `fixed_update()`, shifts values (`current` data becomes `previous` data) and samples a new `current` transform from the objects controlled by the dynamic collision objects.
67+
3. In `update()`, computes render progress inside the current fixed interval:
68+
- `alpha = render_accumulator / fixed_dt`
69+
4. Renders:
70+
- `block1_sprite` from raw `block1` transform.
71+
- `block2_sprite` from interpolated transform (position is interpolated using `vmath.lerp()`, and rotation is interpolated using `vmath.slerp()`).
72+
73+
## Expected Result
74+
75+
At runtime:
76+
- `block1_sprite` appears updated at the fixed frequency.
77+
- `block2_sprite` appears updated each frame.
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
name: "default"
2+
scale_along_z: 0
3+
embedded_instances {
4+
id: "walls"
5+
data: "components {\n"
6+
" id: \"interpolation\"\n"
7+
" component: \"/example/interpolation.script\"\n"
8+
"}\n"
9+
"embedded_components {\n"
10+
" id: \"collisionobject\"\n"
11+
" type: \"collisionobject\"\n"
12+
" data: \"type: COLLISION_OBJECT_TYPE_STATIC\\n"
13+
"mass: 0.0\\n"
14+
"friction: 0.9\\n"
15+
"restitution: 0.1\\n"
16+
"group: \\\"default\\\"\\n"
17+
"mask: \\\"default\\\"\\n"
18+
"embedded_collision_shape {\\n"
19+
" shapes {\\n"
20+
" shape_type: TYPE_BOX\\n"
21+
" position {\\n"
22+
" x: -50.0\\n"
23+
" y: 360.0\\n"
24+
" }\\n"
25+
" rotation {\\n"
26+
" }\\n"
27+
" index: 0\\n"
28+
" count: 3\\n"
29+
" }\\n"
30+
" shapes {\\n"
31+
" shape_type: TYPE_BOX\\n"
32+
" position {\\n"
33+
" x: 770.0\\n"
34+
" y: 360.0\\n"
35+
" }\\n"
36+
" rotation {\\n"
37+
" }\\n"
38+
" index: 3\\n"
39+
" count: 3\\n"
40+
" }\\n"
41+
" shapes {\\n"
42+
" shape_type: TYPE_BOX\\n"
43+
" position {\\n"
44+
" x: 360.0\\n"
45+
" y: 770.0\\n"
46+
" }\\n"
47+
" rotation {\\n"
48+
" }\\n"
49+
" index: 6\\n"
50+
" count: 3\\n"
51+
" }\\n"
52+
" shapes {\\n"
53+
" shape_type: TYPE_BOX\\n"
54+
" position {\\n"
55+
" x: 360.0\\n"
56+
" y: -50.0\\n"
57+
" }\\n"
58+
" rotation {\\n"
59+
" }\\n"
60+
" index: 9\\n"
61+
" count: 3\\n"
62+
" }\\n"
63+
" data: 50.0\\n"
64+
" data: 360.0\\n"
65+
" data: 10.0\\n"
66+
" data: 50.0\\n"
67+
" data: 360.0\\n"
68+
" data: 10.0\\n"
69+
" data: 460.0\\n"
70+
" data: 50.0\\n"
71+
" data: 10.0\\n"
72+
" data: 460.0\\n"
73+
" data: 50.0\\n"
74+
" data: 10.0\\n"
75+
"}\\n"
76+
"\"\n"
77+
"}\n"
78+
""
79+
}
80+
embedded_instances {
81+
id: "block1"
82+
data: "embedded_components {\n"
83+
" id: \"collisionobject\"\n"
84+
" type: \"collisionobject\"\n"
85+
" data: \"type: COLLISION_OBJECT_TYPE_DYNAMIC\\n"
86+
"mass: 20.0\\n"
87+
"friction: 0.0\\n"
88+
"restitution: 1.0\\n"
89+
"group: \\\"default\\\"\\n"
90+
"mask: \\\"default\\\"\\n"
91+
"embedded_collision_shape {\\n"
92+
" shapes {\\n"
93+
" shape_type: TYPE_BOX\\n"
94+
" position {\\n"
95+
" }\\n"
96+
" rotation {\\n"
97+
" }\\n"
98+
" index: 0\\n"
99+
" count: 3\\n"
100+
" }\\n"
101+
" data: 109.4645\\n"
102+
" data: 68.3975\\n"
103+
" data: 10.0\\n"
104+
"}\\n"
105+
"\"\n"
106+
"}\n"
107+
""
108+
position {
109+
x: 220.14
110+
y: 601.457
111+
}
112+
}
113+
embedded_instances {
114+
id: "block2"
115+
data: "embedded_components {\n"
116+
" id: \"collisionobject\"\n"
117+
" type: \"collisionobject\"\n"
118+
" data: \"type: COLLISION_OBJECT_TYPE_DYNAMIC\\n"
119+
"mass: 10.0\\n"
120+
"friction: 0.0\\n"
121+
"restitution: 1.0\\n"
122+
"group: \\\"default\\\"\\n"
123+
"mask: \\\"default\\\"\\n"
124+
"embedded_collision_shape {\\n"
125+
" shapes {\\n"
126+
" shape_type: TYPE_BOX\\n"
127+
" position {\\n"
128+
" }\\n"
129+
" rotation {\\n"
130+
" }\\n"
131+
" index: 0\\n"
132+
" count: 3\\n"
133+
" }\\n"
134+
" data: 68.0\\n"
135+
" data: 68.3975\\n"
136+
" data: 10.0\\n"
137+
"}\\n"
138+
"\"\n"
139+
"}\n"
140+
""
141+
position {
142+
x: 385.289
143+
y: 427.021
144+
}
145+
}
146+
embedded_instances {
147+
id: "block1_sprite"
148+
data: "embedded_components {\n"
149+
" id: \"sprite\"\n"
150+
" type: \"sprite\"\n"
151+
" data: \"default_animation: \\\"elementStone019\\\"\\n"
152+
"material: \\\"/builtins/materials/sprite.material\\\"\\n"
153+
"size {\\n"
154+
" x: 220.0\\n"
155+
" y: 140.0\\n"
156+
"}\\n"
157+
"textures {\\n"
158+
" sampler: \\\"texture_sampler\\\"\\n"
159+
" texture: \\\"/assets/sprites.atlas\\\"\\n"
160+
"}\\n"
161+
"\"\n"
162+
"}\n"
163+
"embedded_components {\n"
164+
" id: \"label\"\n"
165+
" type: \"label\"\n"
166+
" data: \"size {\\n"
167+
" x: 128.0\\n"
168+
" y: 32.0\\n"
169+
"}\\n"
170+
"color {\\n"
171+
" x: 0.101960786\\n"
172+
" y: 0.2\\n"
173+
" z: 0.6\\n"
174+
"}\\n"
175+
"text: \\\"Not interpolated\\\"\\n"
176+
"font: \\\"/builtins/fonts/default.font\\\"\\n"
177+
"material: \\\"/builtins/fonts/label-df.material\\\"\\n"
178+
"\"\n"
179+
"}\n"
180+
""
181+
position {
182+
x: 220.14
183+
y: 601.457
184+
}
185+
}
186+
embedded_instances {
187+
id: "block2_sprite"
188+
data: "embedded_components {\n"
189+
" id: \"sprite\"\n"
190+
" type: \"sprite\"\n"
191+
" data: \"default_animation: \\\"elementStone023\\\"\\n"
192+
"material: \\\"/builtins/materials/sprite.material\\\"\\n"
193+
"size {\\n"
194+
" x: 140.0\\n"
195+
" y: 140.0\\n"
196+
"}\\n"
197+
"textures {\\n"
198+
" sampler: \\\"texture_sampler\\\"\\n"
199+
" texture: \\\"/assets/sprites.atlas\\\"\\n"
200+
"}\\n"
201+
"\"\n"
202+
"}\n"
203+
"embedded_components {\n"
204+
" id: \"label\"\n"
205+
" type: \"label\"\n"
206+
" data: \"size {\\n"
207+
" x: 128.0\\n"
208+
" y: 32.0\\n"
209+
"}\\n"
210+
"color {\\n"
211+
" x: 0.101960786\\n"
212+
" y: 0.2\\n"
213+
" z: 0.6\\n"
214+
"}\\n"
215+
"text: \\\"Interpolated\\\"\\n"
216+
"font: \\\"/builtins/fonts/default.font\\\"\\n"
217+
"material: \\\"/builtins/fonts/label-df.material\\\"\\n"
218+
"\"\n"
219+
"}\n"
220+
""
221+
position {
222+
x: 385.289
223+
y: 427.021
224+
}
225+
}

0 commit comments

Comments
 (0)