engine icon indicating copy to clipboard operation
engine copied to clipboard

GLTF loader result cannot be cloned (SIGSEGV)

Open burner-account opened this issue 5 years ago • 0 comments

The GLTF loader seems to load models just fine, but i stumbled upon a problem while trying to clone the returned core.INode. This is independent of the model file used.

Replication: If you change the g3nd/loader/gltf.go demo function to invoke a Clone call you get a SIGSEGV.

func (t *GltfLoader) loadScene(a *app.App, fpath string) error {
   // .... 
	a.Scene().Add(n.Clone())
	t.prevLoaded = n
	return nil
}

Debug: The Clone function creates a new node, iterates over the children of the original and adds those children to the new node.

The SIGSEGV originates in the engine/core/node.go file, in the setParent function, called via Add.


func (n *Node) Add(ichild INode) *Node {

	setParent(n.GetINode(), ichild)
        // snip ...
}

func setParent(parent INode, child INode) {

	if parent.GetNode() == child.GetNode() {
		panic("Node.{Add,AddAt}: object can't be added as a child of itself")
	}
        // snip ...
}

Now, for some reason the parent INode in setParent is reliably nil somewhere down the road while cloning GLTF nodes. This means, n.GetNode() in the Add function returns a nil inode field. (Maybe a coincidence, but inspecting the child INode in those cases reveals it to be the newly created clone node [1].)

The inode field of the cloned node is nil, because it is not set in the Clone function. The inode is usually set in the NewNode/Init function.


func (n *Node) Clone() INode {

	clone := new(Node)
        // snip
}

Failed attempts:

Changing the Clone function to set the inode stops the SIGSEGV problem but leads to another problem. Now the GLTF is not shown (uninvestigated, yet).

What i do not understand:

Why does the missing inode on the clone of a node containing GLTF lead to SIGSEGV but the cloning of a non-GLTF node does not?

Why is Add ever called with the newly created clone node as child parameter? [1]

Guessworks: My best guess is that since the GLTF loader internally works with int pointers, that there is some unchecked dereferencing going on. (Dereferencing nil int pointer to value 0, using said value 0 as slice index, building some sort of parent-child-loop)

Do you have any ideas on how to proceed?

burner-account avatar Jan 20 '20 02:01 burner-account