g3n / engine

Go 3D Game Engine (http://g3n.rocks)
https://discord.gg/NfaeVr8zDg
BSD 2-Clause "Simplified" License
2.74k stars 292 forks source link

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

Open kimchijoa opened 10 months ago

kimchijoa commented 10 months ago

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)
        }
    }
danaugrs commented 10 months ago

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.

kimchijoa commented 10 months ago

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()))
        }
    })
}
dolanor commented 6 months ago

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)
-       }
    }