feat: add autoZoom param to GIF/MP4 renderers

Adjusts camera distance multiplier from 1.5 to 1.25 when enabled,
reducing empty space around character while leaving room for cosmetics.
This commit is contained in:
devilreef 2026-01-23 01:51:07 +06:00
parent f8947fdcc4
commit fcc495c06f
7 changed files with 29 additions and 13 deletions

View file

@ -14,7 +14,7 @@ import (
)
// RenderGIF renders a GLB model to an animated GIF rotating 360 degrees
func RenderGIF(glbBytes []byte, atlas *texture.Atlas, background string, frames, width, height, delay int, dithering bool) ([]byte, error) {
func RenderGIF(glbBytes []byte, atlas *texture.Atlas, background string, frames, width, height, delay int, dithering, autoZoom bool) ([]byte, error) {
// Parse background color
bgColor, err := ParseHexColor(background)
if err != nil {
@ -41,7 +41,7 @@ func RenderGIF(glbBytes []byte, atlas *texture.Atlas, background string, frames,
go func(frameIdx int) {
defer wg.Done()
rotation := float64(frameIdx) * rotationPerFrame
renderedFrames[frameIdx] = RenderScene(mesh, atlasImage, rotation, width, height, bgColor)
renderedFrames[frameIdx] = RenderScene(mesh, atlasImage, rotation, width, height, bgColor, autoZoom)
}(i)
}
wg.Wait()

View file

@ -12,7 +12,7 @@ import (
)
// RenderMP4 renders a GLB model to an MP4 video rotating 360 degrees
func RenderMP4(glbBytes []byte, atlas *texture.Atlas, background string, frames, width, height, fps int) ([]byte, error) {
func RenderMP4(glbBytes []byte, atlas *texture.Atlas, background string, frames, width, height, fps int, autoZoom bool) ([]byte, error) {
// Parse background color
bgColor, err := ParseHexColor(background)
if err != nil {
@ -47,7 +47,7 @@ func RenderMP4(glbBytes []byte, atlas *texture.Atlas, background string, frames,
go func(frameIdx int) {
defer wg.Done()
rotation := float64(frameIdx) * rotationPerFrame
img := RenderScene(mesh, atlasImage, rotation, width, height, bgColor)
img := RenderScene(mesh, atlasImage, rotation, width, height, bgColor, autoZoom)
// Write frame to temp file
framePath := filepath.Join(tempDir, fmt.Sprintf("frame_%04d.png", frameIdx))

View file

@ -9,7 +9,7 @@ import (
)
// RenderPNG renders a GLB model to PNG with the given parameters
func RenderPNG(glbBytes []byte, atlas *texture.Atlas, rotation float64, background string, width, height int) ([]byte, error) {
func RenderPNG(glbBytes []byte, atlas *texture.Atlas, rotation float64, background string, width, height int, autoZoom bool) ([]byte, error) {
// Parse background color
bgColor, err := ParseHexColor(background)
if err != nil {
@ -26,7 +26,7 @@ func RenderPNG(glbBytes []byte, atlas *texture.Atlas, rotation float64, backgrou
}
// Render the scene
img := RenderScene(mesh, atlasImage, rotation, width, height, bgColor)
img := RenderScene(mesh, atlasImage, rotation, width, height, bgColor, autoZoom)
// Encode to PNG
var buf bytes.Buffer

View file

@ -313,7 +313,7 @@ func quaternionToMatrix(x, y, z, w float64) fauxgl.Matrix {
}
// RenderScene renders a mesh with the given parameters
func RenderScene(mesh *fauxgl.Mesh, atlasImage image.Image, rotationY float64, width, height int, bgColor color.Color) image.Image {
func RenderScene(mesh *fauxgl.Mesh, atlasImage image.Image, rotationY float64, width, height int, bgColor color.Color, autoZoom bool) image.Image {
context := fauxgl.NewContext(width, height)
context.Cull = fauxgl.CullNone
context.AlphaBlend = false
@ -342,7 +342,11 @@ func RenderScene(mesh *fauxgl.Mesh, atlasImage image.Image, rotationY float64, w
far := 100.0
maxDim := math.Max(modelSize.X, math.Max(modelSize.Y, modelSize.Z))
cameraDistance := maxDim / (2 * math.Tan(fauxgl.Radians(fovy/2))) * 1.5
multiplier := 1.5
if autoZoom {
multiplier = 1.25
}
cameraDistance := maxDim / (2 * math.Tan(fauxgl.Radians(fovy/2))) * multiplier
eye := fauxgl.V(modelCenter.X, modelCenter.Y, modelCenter.Z+cameraDistance)
center := modelCenter