Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

experimental "Variant Leak Fixes" causing crashes in ArrayMesh.addSurfaceFromArrays #415

Open
Airyzz opened this issue Mar 1, 2024 · 0 comments

Comments

@Airyzz
Copy link
Contributor

Airyzz commented Mar 1, 2024

Recently upgrading my project to latest version of SwiftGodot, and encountered a crash in this function ArrayMesh.addSurfaceFromArrays.

Thankfully, enabling experimentalDisableVariantUnref does allow to workaround this for now!
Here is the code causing the crash, as requested by the comment on that variable :)

import Foundation
import SwiftGodot

@Godot(.tool)
class Line3D: MeshInstance3D {
    var _vertices = PackedVector3Array()
    var _tangents = PackedVector3Array()
    var _colors = PackedColorArray()
    var _uvs = PackedVector2Array()
    var _indices = PackedInt32Array()

    var _arrays = GArray()

    var time: Float = 0

    @Export
    var width: Double = 1

    @Export
    var alpha: Double = 1

    @Export
    var useGlobalSpace: Bool = false

    @Export(.resourceType, "Gradient")
    var gradient: Gradient = .init()

    @Export(.resourceType, "Curve")
    var widthCurve: Curve = .init()

    @Export
    var points: PackedVector3Array = .init()

    override func _ready() {
        _arrays.resize(size: Mesh.ArrayType.max.rawValue)

        if mesh == nil {
            mesh = ArrayMesh()
        }

        if Engine.isEditorHint() == false {
            mesh = ArrayMesh()
        }

        rebuild()
    }

    override func _process(delta _: Double) {
        if Engine.isEditorHint() {
            rebuild()
        }
    }

    @Callable
    func rebuild() {
        printd("Rebuilding line!")
        guard let am = mesh as? ArrayMesh else {
            return
        }

        printd("Points: \(points)")

        am.clearSurfaces()

        var count = points.size()
        if count < 2 {
            return
        }

        _vertices.resize(newSize: count * 2)
        _tangents.resize(newSize: count * 2)
        _colors.resize(newSize: count * 2)
        _uvs.resize(newSize: count * 2)
        _indices.resize(newSize: count * 2)

        var invGlobalTx: Transform3D? = nil

        if useGlobalSpace {
            invGlobalTx = globalTransform.inverse()
        }

        var half_width = width / 2

        for i in 0 ..< Int(count) {
            var j0 = i * 2
            var j1 = j0 + 1

            var p = points[i]

            if invGlobalTx != nil {
                p = invGlobalTx! * p
            }

            _vertices[j0] = p
            _vertices[j1] = p

            var tangent: Vector3
            if i == 0 {
                tangent = (points[i + 1] - p).normalized()
            } else if i == count - 1 {
                tangent = (p - points[i - 1]).normalized()
            } else {
                tangent = (p - points[i - 1]).lerp(to: points[i + 1] - p, weight: 0.5).normalized()
            }

            _tangents[j0] = tangent
            _tangents[j1] = tangent

            var u = Double(i) / Double(count - 1)
            var c = gradient.sample(offset: u)
            c.alpha = Float(alpha)

            _colors[j0] = c
            _colors[j1] = c

            var v = half_width * widthCurve.sample(offset: u)

            _uvs[j0] = Vector2(x: Float(u), y: Float(-v))
            _uvs[j1] = Vector2(x: Float(u), y: Float(v))

            _indices[j0] = Int32(j0)
            _indices[j1] = Int32(j1)
        }

       // enable this to prevent crash!
       // experimentalDisableVariantUnref = true
        _arrays[Int(Mesh.ArrayType.vertex.rawValue)] = Variant(_vertices)
        _arrays[Int(Mesh.ArrayType.normal.rawValue)] = Variant(_tangents)
        _arrays[Int(Mesh.ArrayType.color.rawValue)] = Variant(_colors)
        _arrays[Int(Mesh.ArrayType.texUv.rawValue)] = Variant(_uvs)
        _arrays[Int(Mesh.ArrayType.index.rawValue)] = Variant(_indices)

        am.addSurfaceFromArrays(primitive: Mesh.PrimitiveType.triangleStrip, arrays: _arrays)
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant