Browse Source

Changed rotation to use vectors instead of quaternions. Fixed getting config number. Fixed game.project settings and updated manual.

paweljarosz 2 weeks ago
parent
commit
5e2e89b04f

BIN
physics/interpolation/engine.png


+ 5 - 6
physics/interpolation/example.md

@@ -19,13 +19,13 @@ The key idea is to separate physics simulation from rendering:
 ## Setup
 
 In `game.project`:
-1. In the `Physics` section set `Use_Fixed_Timestep` enabled and `Max Fixed Timesteps` to e.g. 60.
+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.
 
-![fixed_timestep](fixed_timestep.png)
+![physics](physics.png)
 
 2. In the `Engine` section set `Fixed Update Frequency` to a low value, e.g. 20, so the difference is easy to see.
 
-![fixed_frequency](fixed_freq.png)
+![engine](engine.png)
 
 
 The setup consists of 5 game objects:
@@ -64,10 +64,9 @@ The setup consists of 5 game objects:
    - `previous` = previous fixed physics sample
    - `current` = current fixed physics sample
 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.
-3. Uses quaternion sign compatibility (`vmath.dot`) so rotation interpolation stays stable across sign flips (`q` and `-q` represent the same orientation).
-4. In `update()`, computes render progress inside the current fixed interval:
+3. In `update()`, computes render progress inside the current fixed interval:
    - `alpha = render_accumulator / fixed_dt`
-5. Renders:
+4. Renders:
    - `block1_sprite` from raw `block1` transform.
    - `block2_sprite` from interpolated transform (position is interpolated using `vmath.lerp()`, and rotation is interpolated using `vmath.slerp()`).
 

+ 3 - 18
physics/interpolation/example/interpolation.script

@@ -13,7 +13,7 @@ local interpolated_block = {
 }
 
 -- Store fixed update interval in seconds from game.project Fixed Update Frequency.
-local fixed_dt = 1 / tonumber(sys.get_config("engine.fixed_update_frequency")) or 20
+local fixed_dt = 1 / (sys.get_config_number("engine.fixed_update_frequency") or 20)
 
 function init(self)
 	-- Render-time remainder inside the current fixed-step interval.
@@ -29,28 +29,13 @@ function init(self)
 	self.current_fixed_rotation = self.previous_fixed_rotation
 end
 
--- Helper function to make quaternions compatible with each other
--- and prevent abrupt rotation flips when interpolating.
-local function quat_make_compatible(reference, q)
-	-- q and -q are the same orientation, but interpolation chooses different paths.
-	-- We keep quaternion sign continuous using a dot-product hemisphere check:
-	-- dot < 0 means "opposite hemisphere", so we flip sign to avoid rotation flips.
-	local reference_v4 = vmath.vector4(reference.x, reference.y, reference.z, reference.w)
-	local q_v4 = vmath.vector4(q.x, q.y, q.z, q.w)
-	if vmath.dot(reference_v4, q_v4) < 0 then
-		return vmath.quat(-q.x, -q.y, -q.z, -q.w)
-	end
-	return q
-end
-
 function fixed_update(self, dt)
 	-- Shift the transform data from current state to previous state 
 	-- and sample new fixed state from the game object with the dynamic collision object component.
 	self.previous_fixed_position = self.current_fixed_position
 	self.previous_fixed_rotation = self.current_fixed_rotation
 	self.current_fixed_position = go.get_position(interpolated_block.physics_go)
-	local sampled_rotation = go.get_rotation(interpolated_block.physics_go)
-	self.current_fixed_rotation = quat_make_compatible(self.previous_fixed_rotation, sampled_rotation)
+	self.current_fixed_rotation = go.get_rotation(interpolated_block.physics_go)
 end	
 
 function update(self, dt)
@@ -80,7 +65,7 @@ function update(self, dt)
 	-- Position interpolation is linear (lerp).
 	local interpolated_position = self.previous_fixed_position + position_difference * alpha
 
-	-- Rotation interpolation is spherical (slerp), with sign-compatible quaternions.
+	-- Rotation interpolation is spherical (slerp).
 	local interpolated_rotation = vmath.slerp(alpha, self.previous_fixed_rotation, self.current_fixed_rotation)
 
 	-- Render blended transform.

BIN
physics/interpolation/fixed_freq.png


BIN
physics/interpolation/fixed_timestep.png


+ 1 - 2
physics/interpolation/game.project

@@ -18,8 +18,7 @@ high_dpi = 1
 scale = 0.02
 gravity_y = -500.0
 use_fixed_timestep = 1
-max_fixed_timesteps = 60
-allow_dynamic_transforms = 1
+velocity_threshold = 50.0
 
 [script]
 shared_state = 1

BIN
physics/interpolation/physics.png