render3d: actor_own_skin / skin_clone_free, and a frame's scratch and tables made with the device

actor_own_skin(a) gives an actor its own clone of its model's skeleton and actor_release frees it
(skin_clone_free: the pose, matrices, views and scratch the clone made; the rest data stays its
source's). gvk_startup_state, at the end of gvk_init, makes the scratch and tables a draw used to
make on first need (gvk_tmp_buf, the pipeline fast cache, the set key and per-program uniform
offsets pre-sized to 4096 programs, skip/seen/size words, spare and retired lists, the grass cull's
words), and those frame paths no longer start them. Compiled (steady).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-28 16:02:21 +03:00
parent dec64e8a59
commit f4e121ae94
6 changed files with 69 additions and 29 deletions

View file

@ -34,6 +34,7 @@ property Actor {
cutout: bool = false, # alpha-tested (a flame's cards)
emissive: float = 0.0, # float bits: self-lit strength
skin: Skin, # this instance's own pose (skin_clone); null: the model's
skin_owned: bool = false, # made by actor_own_skin: actor_release frees it
ptint: words, # 4 per primitive: on flag, r, g, b (a part's own colour)
hide: words, # 1 per primitive: skip it (a cap taken off)
radius: float = 0.0, # float bits: bounding radius for culling (0 = never culled)
@ -443,7 +444,7 @@ function actor_fresh(render3d_st: mut Render3dState) -> Actor {
m4_identity(a.mat)
a.visible = true; a.cast_hidden = false; a.casts = true; a.row = -1
a.cutout = false; a.emissive = 0.0; a.radius = 0.0; a.cull = 0.0; a.outline = 0.0
a.skin = null; a.ocol = null
a.skin = null; a.skin_owned = false; a.ocol = null
return a
}
@ -455,8 +456,21 @@ function actor_release(render3d_st: mut Render3dState, a: Actor) -> void {
actor_remove(render3d_st, a)
if a.ptint != null { free(a.ptint); a.ptint = null }
if a.hide != null { free(a.hide); a.hide = null }
if a.skin_owned and a.skin != null { skin_clone_free(a.skin) }
a.skin_owned = false
a.model = null; a.skin = null; a.ocol = null
a.id = 0
if render3d_st.ac_spare == null { render3d_st.ac_spare = new []Actor }
push(render3d_st.ac_spare, a)
}
# The actor poses on its own copy of its model's skeleton (a person, an animal), which it keeps until
# actor_release gives it back with the record: a clone made by the caller and dropped with the actor
# was one kept skeleton per figure ever placed.
function actor_own_skin(a: Actor) -> Skin {
if a == null or a.model == null or a.model.skin == null { return null }
if a.skin_owned and a.skin != null { skin_clone_free(a.skin) }
a.skin = skin_clone(a.model.skin)
a.skin_owned = true
return a.skin
}