2024-12-16 12:24:09 +00:00
|
|
|
package assetmanager
|
|
|
|
|
|
|
|
import (
|
2024-12-17 00:16:17 +00:00
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"regexp"
|
|
|
|
"slices"
|
|
|
|
"strings"
|
2024-12-16 12:24:09 +00:00
|
|
|
|
2024-12-17 00:16:17 +00:00
|
|
|
"git.tek.govt.hu/dowerx/opengl-deferred/types/asset"
|
2024-12-16 12:24:09 +00:00
|
|
|
"git.tek.govt.hu/dowerx/opengl-deferred/types/geometry"
|
2024-12-17 01:59:59 +00:00
|
|
|
"git.tek.govt.hu/dowerx/opengl-deferred/types/material"
|
2024-12-16 12:24:09 +00:00
|
|
|
"git.tek.govt.hu/dowerx/opengl-deferred/types/shader"
|
|
|
|
"git.tek.govt.hu/dowerx/opengl-deferred/types/texture"
|
|
|
|
)
|
|
|
|
|
|
|
|
type AssetManager struct {
|
2024-12-17 00:16:17 +00:00
|
|
|
assets map[string]asset.Asset
|
2024-12-16 12:24:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var instance *AssetManager
|
|
|
|
|
|
|
|
var (
|
2024-12-17 00:16:17 +00:00
|
|
|
TEXTURE_EXTENSIONS = []string{"png", "tif"}
|
|
|
|
GEOMETRY_EXTENSIONS = []string{"obj"}
|
|
|
|
SHADER_EXTENSIONS = []string{"sdr"}
|
2024-12-17 01:59:59 +00:00
|
|
|
MATERIAL_EXTENSIONS = []string{"mtl"}
|
|
|
|
SCENE_EXTENSIONS = []string{"scn"}
|
2024-12-17 00:16:17 +00:00
|
|
|
|
|
|
|
VERTEX_REGEX = regexp.MustCompile("vertex_file (?P<path>.*)$")
|
|
|
|
FRAGMENT_REGEX = regexp.MustCompile("fragment_file (?P<path>.*)$")
|
2024-12-16 12:24:09 +00:00
|
|
|
)
|
|
|
|
|
2024-12-17 00:16:17 +00:00
|
|
|
func (a *AssetManager) loadItem(path string, itemToLoad os.DirEntry) error {
|
|
|
|
if itemToLoad.Type().IsDir() {
|
|
|
|
items, err := os.ReadDir(filepath.Join(path, itemToLoad.Name()))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, item := range items {
|
|
|
|
if err = a.loadItem(filepath.Join(path, itemToLoad.Name()), item); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if itemToLoad.Type().IsRegular() {
|
|
|
|
parts := strings.Split(itemToLoad.Name(), ".")
|
|
|
|
extension := parts[len(parts)-1]
|
|
|
|
|
|
|
|
var asset asset.Asset
|
|
|
|
var err error
|
|
|
|
|
|
|
|
if slices.Contains(TEXTURE_EXTENSIONS, extension) {
|
|
|
|
asset, err = texture.Load(filepath.Join(path, itemToLoad.Name()))
|
|
|
|
} else if slices.Contains(GEOMETRY_EXTENSIONS, extension) {
|
|
|
|
asset, err = geometry.LoadOBJ(filepath.Join(path, itemToLoad.Name()))
|
|
|
|
} else if slices.Contains(SHADER_EXTENSIONS, extension) {
|
|
|
|
definition, err := os.ReadFile(filepath.Join(path, itemToLoad.Name()))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
var vertexPath, fragmentPath string
|
|
|
|
for _, line := range strings.Split(string(definition), "\n") {
|
|
|
|
var matches []string
|
|
|
|
|
|
|
|
if matches = VERTEX_REGEX.FindStringSubmatch(line); matches != nil {
|
|
|
|
vertexPath = matches[VERTEX_REGEX.SubexpIndex("path")]
|
|
|
|
} else if matches = FRAGMENT_REGEX.FindStringSubmatch(line); matches != nil {
|
|
|
|
fragmentPath = matches[FRAGMENT_REGEX.SubexpIndex("path")]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
asset, err = shader.FromFiles(filepath.Join(path, vertexPath), filepath.Join(path, fragmentPath))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-12-17 01:59:59 +00:00
|
|
|
} else if slices.Contains(MATERIAL_EXTENSIONS, extension) {
|
|
|
|
asset, err = material.Load(filepath.Join(path, itemToLoad.Name()), a.assets)
|
2024-12-17 00:16:17 +00:00
|
|
|
} else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
a.assets[filepath.Join(path, itemToLoad.Name()[:len(itemToLoad.Name())-len(extension)-1])] = asset
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func Init(path string) (*AssetManager, error) {
|
2024-12-16 12:24:09 +00:00
|
|
|
if instance != nil {
|
2024-12-17 00:16:17 +00:00
|
|
|
instance.Destroy()
|
2024-12-16 12:24:09 +00:00
|
|
|
}
|
|
|
|
|
2024-12-17 00:16:17 +00:00
|
|
|
instance = &AssetManager{make(map[string]asset.Asset)}
|
|
|
|
|
|
|
|
items, err := os.ReadDir(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, item := range items {
|
|
|
|
err = instance.loadItem(path, item)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2024-12-16 12:24:09 +00:00
|
|
|
}
|
|
|
|
|
2024-12-17 01:59:59 +00:00
|
|
|
for k, asset := range instance.assets {
|
|
|
|
material, ok := asset.(material.Material)
|
|
|
|
if ok {
|
|
|
|
material.AttachAssets(instance.assets)
|
|
|
|
instance.assets[k] = material
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-17 00:16:17 +00:00
|
|
|
fmt.Println("Loaded assets:")
|
|
|
|
for k := range instance.assets {
|
|
|
|
fmt.Printf(" %s\n", k)
|
|
|
|
}
|
|
|
|
|
|
|
|
return instance, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func Get() *AssetManager {
|
2024-12-16 12:24:09 +00:00
|
|
|
return instance
|
|
|
|
}
|
|
|
|
|
2024-12-17 01:59:59 +00:00
|
|
|
func GetAsset[T asset.Asset](a *AssetManager, name string) *T {
|
|
|
|
value, ok := a.assets[name].(T)
|
2024-12-17 00:16:17 +00:00
|
|
|
if !ok {
|
|
|
|
return nil
|
2024-12-16 12:24:09 +00:00
|
|
|
}
|
2024-12-17 00:16:17 +00:00
|
|
|
return &value
|
|
|
|
}
|
2024-12-16 12:24:09 +00:00
|
|
|
|
2024-12-17 00:16:17 +00:00
|
|
|
func (a *AssetManager) Destroy() {
|
|
|
|
for _, item := range a.assets {
|
|
|
|
item.Delete()
|
2024-12-16 12:24:09 +00:00
|
|
|
}
|
|
|
|
}
|