engine icon indicating copy to clipboard operation
engine copied to clipboard

Is there a place where I can see examples of using g3n?

Open kimchijoa opened this issue 2 years ago • 3 comments

Hello, I'm trying to create a 3d modeling viewer using g3n-engine now.

However, I am having difficulty using it because there are not many examples of use.

There are parts of g3nd(Demo) and g3n that behave differently, so I want to see an example of this, where can I see it?

When I create a 3d modeling viewer based on g3nd, I can't play animation because it becomes nil pointer in certain parts.

I want to see an example of using animation in gtlf loader. Thank you.

type GltfLoader struct {
	prevLoaded core.INode
	anims      animation.Animation
}

var t *GltfLoader

...(main func inner)....
for i := range g.Animations {
		anim, err := g.LoadAnimation(i)
		anim.SetLoop(true)
		t.anims = append(t.anims, anim)    <--- this is nil pointer
		if err != nil {
			fmt.Println("Load Animation Err : ", err)
		}
	}


kimchijoa avatar Nov 02 '23 06:11 kimchijoa

Hi! G3ND uses the most recent tagged version of G3N, which is older than the latest commit. I'd guess that's why you're seeing discrepancies. The G3ND example loader -> gltf shows GLTF animations that you could use as starting point. If you find a bug, please post a minimal reproducible example and I or someone else may be able to take a look.

danaugrs avatar Nov 02 '23 14:11 danaugrs

Thank you for the comments. Come to think of it, I didn't post the example code I wrote. I will attach the code I used below Could you have a look at it?

//main.go

package main

import (
	"fmt"
	"path/filepath"
	"time"

	"github.com/g3n/engine/animation"
	"github.com/g3n/engine/app"
	"github.com/g3n/engine/camera"
	"github.com/g3n/engine/core"
	"github.com/g3n/engine/gls"
	"github.com/g3n/engine/gui"
	"github.com/g3n/engine/light"
	"github.com/g3n/engine/loader/gltf"
	"github.com/g3n/engine/math32"
	"github.com/g3n/engine/renderer"
	"github.com/g3n/engine/util/helper"
	"github.com/g3n/engine/window"
)

type GltfLoader struct {
	prevLoaded core.INode
	anims      animation.Animation
}

var t *GltfLoader

func main() {
	fmt.Println("Create app, camera")
	// Create application and scene
	a := app.App(1920, 1080, "g3n Test")
	scene := core.NewNode()

	// Set the scene to be managed by the gui manager
	gui.Manager().Set(scene)

	// Create perspective camera
	cam := camera.New(1)
	cam.SetPosition(0, 0, 3)
	scene.Add(cam)

	// Set up orbit control for the camera
	camera.NewOrbitControl(cam)

	// Set up callback to update viewport and camera aspect ratio when the window is resized
	onResize := func(evname string, ev interface{}) {
		// Get framebuffer size and update viewport accordingly
		width, height := a.GetSize()
		a.Gls().Viewport(0, 0, int32(width), int32(height))
		// Update the camera's aspect ratio
		cam.SetAspect(float32(width) / float32(height))
	}
	a.Subscribe(window.OnWindowSize, onResize)
	onResize("", nil)

	//====================================================================================================================================================
	//Create and add loader
	fmt.Println("Create external gtlf file model")
	fpath := "C:/Users/kh/Documents/golang/src/g3n-engine/test-gltf/BrainStem.gltf" //<-- local gltf file

	fmt.Println("read file")
	ext := filepath.Ext(fpath)
	var g *gltf.GLTF
	var err error

	//check extension
	fmt.Println("== ext is : ", ext)
	if ext == ".gltf" {
		g, err = gltf.ParseJSON(fpath)
	} else if ext == ".glb" {
		g, err = gltf.ParseBin(fpath)
	}

	if err != nil {
		fmt.Println("err Parse : ", err)
		return
	}

	defaultScenIdx := 0
	if g.Scene != nil {
		defaultScenIdx = *g.Scene
	}
	fmt.Println("Load Mesh")
	n, err := g.LoadMesh(defaultScenIdx)
	if err != nil {
		fmt.Println("Load Failed : ", err)
		return
	}

	fmt.Println("Looping Animation")
	for i := range g.Animations {
		anim, err := g.LoadAnimation(i)
		anim.SetLoop(true)
		t.anims = append(t.anims, anim)   //<=== #ISUUE t.ainms is nullPoint 
		if err != nil {
			fmt.Println("Load Animation Err : ", err)
		}
	}
	fmt.Println("add Scene")
	scene.Add(n)
	//====================================================================================================================================================

	// Create and add lights to the scene
	scene.Add(light.NewAmbient(&math32.Color{1.0, 1.0, 1.0}, 0.8))
	pointLight := light.NewPoint(&math32.Color{1, 1, 1}, 5.0)
	pointLight.SetPosition(1, 0, 2)
	scene.Add(pointLight)

	// Create and add an axis helper to the scene
	scene.Add(helper.NewAxes(0.5))

	// Set background color to gray
	a.Gls().ClearColor(0.5, 0.5, 0.5, 1.0)

	// Run the application
	a.Run(func(renderer *renderer.Renderer, deltaTime time.Duration) {
		a.Gls().Clear(gls.DEPTH_BUFFER_BIT | gls.STENCIL_BUFFER_BIT | gls.COLOR_BUFFER_BIT)
		renderer.Render(scene, cam)
		//Loop Animation
		for _, anim := range t.anims {
			anim.Update(float32(deltaTime.Seconds()))
		}
	})
}

kimchijoa avatar Nov 03 '23 07:11 kimchijoa

You can see a use of animation from a gltf model here: https://github.com/529124368/golang_diablo3D

I think one of the problem you have in your code, is that you check for the error after using the pointer, which happens to be nil, and might make you program fail.

	for i := range g.Animations {
		anim, err := g.LoadAnimation(i)
+		if err != nil {
+			fmt.Println("Load Animation Err : ", err)
+		}
		anim.SetLoop(true)
		t.anims = append(t.anims, anim)   //<=== #ISUUE t.ainms is nullPoint 
-		if err != nil {
-			fmt.Println("Load Animation Err : ", err)
-		}
	}

dolanor avatar Mar 07 '24 23:03 dolanor