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

GLTF loader result cannot be cloned (SIGSEGV) #163

Open
burner-account opened this issue Jan 20, 2020 · 0 comments
Open

GLTF loader result cannot be cloned (SIGSEGV) #163

burner-account opened this issue Jan 20, 2020 · 0 comments

Comments

@burner-account
Copy link

burner-account commented Jan 20, 2020

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?

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