Skip to content

set_animation range on glTF model doesn't apply correctly #16817

@GreenXenith

Description

@GreenXenith

Luanti version

5.14.0

@appgurueu asked me to open an issue, I have not tested on 5.15.0.

Operating system and version

Xubuntu 24.04.3

GPU model

AMD Radeon RX 6700

Active renderer

4.6 / opengl / SDL 2.30.0

Summary

Trying to set any frame range other than the entire exported animation either doesn't change anything or behaves strangely. I won't try to ascertain the specific behavior, i've simply observed:

  • range 0-1 and range 0-0.5 are identical
  • Anything beyond 0.5 is considered 1
  • (>=1)-(<=0.5ish) does ... something spastic, but 1-(>=0.5ish) does nothing

Steps to reproduce

My simple glTF test model is a single default cube with a single bone at default position parented with automatic weights. Keyframe 1 at rest position, keyframe 10 at 90 degrees about the X axis. Changed interpolation to linear. Cube map UV unwrap if you feel so inclined. Absolutely no custom export settings, these happen to be my defaults:

Expand Image

I exported a glb but here is the gltf if it helps:

Expand
{
	"asset":{
		"generator":"Khronos glTF Blender I/O v4.5.47",
		"version":"2.0"
	},
	"scene":0,
	"scenes":[
		{
			"name":"Scene",
			"nodes":[
				2
			]
		}
	],
	"nodes":[
		{
			"name":"Bone"
		},
		{
			"mesh":0,
			"name":"Cube",
			"skin":0
		},
		{
			"children":[
				1,
				0
			],
			"name":"Armature"
		}
	],
	"animations":[
		{
			"channels":[
				{
					"sampler":0,
					"target":{
						"node":0,
						"path":"translation"
					}
				},
				{
					"sampler":1,
					"target":{
						"node":0,
						"path":"rotation"
					}
				},
				{
					"sampler":2,
					"target":{
						"node":0,
						"path":"scale"
					}
				}
			],
			"name":"ArmatureAction",
			"samplers":[
				{
					"input":7,
					"interpolation":"STEP",
					"output":8
				},
				{
					"input":9,
					"interpolation":"LINEAR",
					"output":10
				},
				{
					"input":7,
					"interpolation":"STEP",
					"output":11
				}
			]
		}
	],
	"meshes":[
		{
			"name":"Cube.001",
			"primitives":[
				{
					"attributes":{
						"POSITION":0,
						"NORMAL":1,
						"TEXCOORD_0":2,
						"JOINTS_0":3,
						"WEIGHTS_0":4
					},
					"indices":5
				}
			]
		}
	],
	"skins":[
		{
			"inverseBindMatrices":6,
			"joints":[
				0
			],
			"name":"Armature"
		}
	],
	"accessors":[
		{
			"bufferView":0,
			"componentType":5126,
			"count":24,
			"max":[
				1,
				1,
				1
			],
			"min":[
				-1,
				-1,
				-1
			],
			"type":"VEC3"
		},
		{
			"bufferView":1,
			"componentType":5126,
			"count":24,
			"type":"VEC3"
		},
		{
			"bufferView":2,
			"componentType":5126,
			"count":24,
			"type":"VEC2"
		},
		{
			"bufferView":3,
			"componentType":5121,
			"count":24,
			"type":"VEC4"
		},
		{
			"bufferView":4,
			"componentType":5126,
			"count":24,
			"type":"VEC4"
		},
		{
			"bufferView":5,
			"componentType":5123,
			"count":36,
			"type":"SCALAR"
		},
		{
			"bufferView":6,
			"componentType":5126,
			"count":1,
			"type":"MAT4"
		},
		{
			"bufferView":7,
			"componentType":5126,
			"count":2,
			"max":[
				0.4166666666666667
			],
			"min":[
				0.041666666666666664
			],
			"type":"SCALAR"
		},
		{
			"bufferView":8,
			"componentType":5126,
			"count":2,
			"type":"VEC3"
		},
		{
			"bufferView":9,
			"componentType":5126,
			"count":10,
			"max":[
				0.4166666666666667
			],
			"min":[
				0.041666666666666664
			],
			"type":"SCALAR"
		},
		{
			"bufferView":10,
			"componentType":5126,
			"count":10,
			"type":"VEC4"
		},
		{
			"bufferView":11,
			"componentType":5126,
			"count":2,
			"type":"VEC3"
		}
	],
	"bufferViews":[
		{
			"buffer":0,
			"byteLength":288,
			"byteOffset":0,
			"target":34962
		},
		{
			"buffer":0,
			"byteLength":288,
			"byteOffset":288,
			"target":34962
		},
		{
			"buffer":0,
			"byteLength":192,
			"byteOffset":576,
			"target":34962
		},
		{
			"buffer":0,
			"byteLength":96,
			"byteOffset":768,
			"target":34962
		},
		{
			"buffer":0,
			"byteLength":384,
			"byteOffset":864,
			"target":34962
		},
		{
			"buffer":0,
			"byteLength":72,
			"byteOffset":1248,
			"target":34963
		},
		{
			"buffer":0,
			"byteLength":64,
			"byteOffset":1320
		},
		{
			"buffer":0,
			"byteLength":8,
			"byteOffset":1384
		},
		{
			"buffer":0,
			"byteLength":24,
			"byteOffset":1392
		},
		{
			"buffer":0,
			"byteLength":40,
			"byteOffset":1416
		},
		{
			"buffer":0,
			"byteLength":160,
			"byteOffset":1456
		},
		{
			"buffer":0,
			"byteLength":24,
			"byteOffset":1616
		}
	],
	"buffers":[
		{
			"byteLength":1640,
			"uri":"data:application/octet-stream;base64,AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAIA/AACAPwAAAAAAAIA/AACAPwAAAAAAAIA/AACAPwAAAAAAAAAAAACAPwAAgD8AAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAgAFAAsAAgALAAgABgAJABUABgAVABIAFAAXABEAFAARAA4ADAAPAAMADAADAAAABwATAA0ABwANAAEAFgAKAAQAFgAEABAAAACAPwAAAIAAAAAAAAAAgAAAAIAAAIA/AAAAgAAAAAAAAAAAAAAAgAAAgD8AAACAAAAAgAAAAAAAAACAAACAP6uqKj1VVdU+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAq6oqPauqqj0AAAA+q6oqPlVVVT4AAIA+VVWVPquqqj4AAMA+VVXVPgAAAAAAAAAAAAAAAAAAgD/fxaU9AAAAAAAAAAD1KH8/Q7opPgAAAAAAAAAAf3V8PyZlgT4AAAAAAAAAAJWwdz+2+q0+AAAAAAAAAABhxHA/YHnZPgAAAAAAAAAAUMJnPyRlAT8AAAAAAAAAACTkXD/5ghQ/AAAAAAAAAADxhFA/4cUlPwAAAAAAAAAA5xNDP/UENT8AAAAAAAAAAPEENT8AAIA/AACAPwAAgD8AAIA/AQCAPwEAgD8="
		}
	]
}

Register an entity and set the animation on_activate. Play with ranges. I made some janky test code to control the range/speed with a command.

local t_x, t_y, t_s = 0, 1, 1

core.register_entity("test:noaction", {
    initial_properties = {
        visual = "mesh",
        mesh = "noaction.glb",
        textures = {"default_dirt.png"},
    },
    anim = function(self)
        self._t_x, self._t_y, self._t_s = t_x, t_y, t_s
        self.object:set_animation({x = self._t_x, y = self._t_y}, self._t_s, 0, true)
    end,
    on_activate = function(self)
        self:anim()
    end,
    on_step = function(self)
        if t_x ~= self._t_x or t_y ~= self._t_y or t_s ~= self._t_s then
            self:anim()
        end
    end,
})

core.register_chatcommand("anim", {
    func = function(_, param)
        local p = param:split(" ")
        t_x, t_y, t_s = tonumber(p[1]) or t_x, tonumber(p[2]) or t_y, tonumber(p[3]) or t_s
    end
})

Metadata

Metadata

Assignees

No one assigned

    Labels

    @ DocumentationImprovements or additions to documentation@ Script APIUnconfirmed bugBug report that has not been confirmed to exist/be reproducible

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions