AssetManagerLinker Interface

hello everyone im currently learning the jme platform while making a simple platformer

i made an interface and implemented it throught hasmaps and i think this code will help some pepole so here is it:

for the id i use enums and i think it will make every project more organized

[java]public interface AssetManagerLinker {

void addTexture(int id,String texPath);

void addModel(int id,Spatial spatial);

void addSound(int id,String soundPath);

void addMaterial(String string,Material mat);

Material getMaterial(int id);

Texture getTexture(int id);

AudioNode getSound(int id);

Spatial getModel(int id);

}[/java]

:?

wrong place to put this?

More that we don’t understand what it’s for/how it helps…

1 Like

All assets are defined by their asset key name, e.g. “Textures/Backgrounds/Background1.png”, thats their “id”.

whenu use enums for the ints it allow u to use auto complete in the compiler in it makes your code alot more organized.

anyway i will upload the implementaion also but i need to do some changes for it to be not depended on my classes

to normen : i underStand what u say

but the platform do not aplly somehow connecting enums to assets so it will be more organized

@groover said:
whenu use enums for the ints it allow u to use auto complete in the compiler in it makes your code alot more organized.
anyway i will upload the implementaion also but i need to do some changes for it to be not depended on my classes


So you're saying an enum should be created for each texture or material (or whatever) to reflect the one that might be using?

I might just misunderstand the usage.

Let's say I have something like the following code. When I use getMaterial(), what is it I'm supposed to return with your interface?:
[java]
switch (((Planet) objectInView).getType()) {
case Gas:
panelMaterial = app.getAssetManager().loadMaterial("Materials/Planets/GasGiantLUT.j3m").clone();
panelMaterial.setTexture("LUT", lutTex);
panelMaterial.setColor("Color", color);
panelMaterial.setFloat("Seed", ((Planet) objectInView).getSeed());
panelMaterial.setFloat("Radius", ((Planet) objectInView).getRadius());
break;
case Ice:
panelMaterial = app.getAssetManager().loadMaterial("Materials/Planets/IceGiantLUT.j3m").clone();
panelMaterial.setTexture("LUT", lutTex);
panelMaterial.setColor("Color", color);
panelMaterial.setFloat("Seed", ((Planet) objectInView).getSeed());
panelMaterial.setFloat("Radius", ((Planet) objectInView).getRadius());
break;
case Rocky:
panelMaterial = app.getAssetManager().loadMaterial("Materials/Planets/RockyLUT.j3m").clone();
panelMaterial.setTexture("LUT", lutTex);
panelMaterial.setColor("Color", ColorRGBA.White.clone());
panelMaterial.setFloat("Seed", ((Planet) objectInView).getSeed());
panelMaterial.setFloat("Radius", ((Planet) objectInView).getRadius());
break;
case RockyHot:
panelMaterial = app.getAssetManager().loadMaterial("Materials/Planets/RockyLUT.j3m").clone();
panelMaterial.setTexture("LUT", lutTex);
panelMaterial.setColor("Color", ColorRGBA.White.clone());
panelMaterial.setFloat("Seed", ((Planet) objectInView).getSeed());
panelMaterial.setFloat("Radius", ((Planet) objectInView).getRadius());
break;
case RockyCold:
panelMaterial = app.getAssetManager().loadMaterial("Materials/Planets/RockyLUT.j3m").clone();
panelMaterial.setTexture("LUT", lutTex);
panelMaterial.setColor("Color", ColorRGBA.White.clone());
panelMaterial.setFloat("Seed", ((Planet) objectInView).getSeed());
panelMaterial.setFloat("Radius", ((Planet) objectInView).getRadius());
break;
default:
}
[/java]

again u misunderstood

a material,texture,Spatial and audio are all for the same model

here is in your code madjack:

MyType is a enum

[java]

MyType type= ((Planet) objectInView).getType())

panelMaterial=assetLinker.getMaterial(type);



[/java]





but u need to make methods in assetLinker that init those vallues ;

anyway this would be nice method

[java]



public void addMaterial(String matPath,Texture lutTex,ColorRGBA color,float seed,float radius)

{

Material panelMaterial = app.getAssetManager().loadMaterial(matPath).clone();

panelMaterial.setTexture("LUT", lutTex);

panelMaterial.setColor("Color", color);

panelMaterial.setFloat("Seed", seed);

panelMaterial.setFloat("Radius", radius);

materialsMap.put(MyType.WhatEverMAterial,panelMaterial)

}

[/java]





break;

Not always though. I have one texture used in several models and another model that can have three different textures depending on what is happening.

u can easyly modify the interface to get multiple arguments for texture or whatever

somtThing like



[java]

publuc void addMaterial(

public void addMaterial(String matPath,Texture lutTex,ColorRGBA color,float seed,float radius)

{

Material panelMaterial = app.getAssetManager().loadMaterial(matPath).clone();

panelMaterial.setTexture("LUT", lutTex);

panelMaterial.setColor("Color", color);

panelMaterial.setFloat("Seed", seed);

panelMaterial.setFloat("Radius", radius);

materialStuff=materialsMap.get(MyType id);

if(materialStuff!=null)

materialStuff.put(SomeOtherClass,panelMaterial);

}



[/java]

[java]

package HelperClasses;



import Interfaces.managers.AssetManagerLinker;



import com.jme3.audio.AudioNode;

import com.jme3.material.Material;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.Spatial;

import com.jme3.scene.shape.Box;

import com.jme3.texture.Texture;



import enums.ModelID;

import enums.WorldType;

import java.util.EnumMap;

import java.util.HashMap;

import mygame.Main;



/**

*

  • @author shahar

    */

    public class AssetLinker implements AssetManagerLinker{

    private HashMap<String,Material> materialsMap;

    private EnumMap<ModelID,EnumMap<WorldType,Texture>> texturesMap;

    private EnumMap<ModelID,Spatial> spatialsMap;

    private EnumMap<ModelID,EnumMap<WorldType,AudioNode>> soundsMap;

    private Main app;

    public AssetLinker(Main app) {

    this.app=app;

    soundsMap=new EnumMap<ModelID, EnumMap<WorldType, AudioNode>>(ModelID.class);

    texturesMap=new EnumMap<ModelID, EnumMap<WorldType, Texture>>(ModelID.class);

    spatialsMap=new EnumMap<ModelID, Spatial>(ModelID.class);

    materialsMap=new HashMap<String, Material>();

    }















    public void addTexture(WorldType world, ModelID id, Texture tex) {

    EnumMap<WorldType,Texture> map;

    if(texturesMap.get(id)!=null)

    texturesMap.get(id).put(world, tex);

    else

    {

    map=new EnumMap<WorldType, Texture>(WorldType.class);

    map.put(world, tex);

    texturesMap.put(id, map);

    }

    }



    public void addModel(ModelID id, Spatial spatial) {

    spatialsMap.put(id, spatial);

    }





    public Material getMaterial(String matName) {

    return materialsMap.get(matName);

    }









    public void addMaterial(String matPath, Material mat) {

    materialsMap.put(matPath, mat);

    }



    public Material getMaterial(ModelID id) {

    return materialsMap.get(id);

    }



    public Texture getTexture(WorldType world, ModelID id) {

    if(texturesMap.get(id)!=null)

    return texturesMap.get(id).get(world);

    else

    return null;

    }



    public AudioNode getSound(ModelID id,WorldType world) {

    if(soundsMap.get(id)!=null)

    return soundsMap.get(id).get(world);

    else

    return null;

    }



    public Spatial getModel(ModelID id) {

    Spatial model=spatialsMap.get(id);

    if(model!=null)

    return model.clone();

    else

    return null;

    }

    private void addCubeModel(float x,float y,float z,String materialName,ModelID name) {

    Spatial spatial=makeCube("Cube", Vector3f.ZERO, x, y, z, materialsMap.get(materialName));

    spatialsMap.put(name, spatial);

    }





    public void addSound(WorldType world, ModelID id, String soundPath) {

    if(soundsMap.get(id)!=null)

    {

    soundsMap.get(id).put(world, new AudioNode(app.getAssetManager(), soundPath));

    }



    }



    protected void MakeAndAddModel(String modelPath, String MaterialName,ModelID name) {

    Spatial spatial=app.getAssetManager().loadModel(modelPath);

    if(MaterialName!=null)

    spatial.setMaterial(materialsMap.get(MaterialName));

    addModel(name, spatial);

    }

    protected void MakeAndAddMaterial(String materialpath,String name) {

    materialsMap.put(name, app.getAssetManager().loadMaterial(materialpath));

    }

    public Geometry makeCube(String name,Vector3f loc,float x,float y,float z,Material mat)

    {

    Box box = new Box(loc, x, y, z);

    Geometry cube = new Geometry(name, box);

    cube.setMaterial(mat);

    return cube;

    }

    public void initSpatials() {



    }



    public void initMaterials() {



    }



    public void initSounds() {



    }



    public void initTextures() {



    }







    }



    [/java]



    well here the code u can modify and extend it to your pleasure

    and here the new interface



    [java]

    package Interfaces.managers;



    import com.jme3.audio.AudioNode;

    import com.jme3.material.Material;

    import com.jme3.scene.Spatial;

    import com.jme3.texture.Texture;

    import enums.ModelID;

    import enums.WorldType;



    /**

    *
  • @author shahar

    */

    public interface AssetManagerLinker {

    void addTexture(WorldType world,ModelID id,Texture tex);

    void addModel(ModelID id,Spatial spatial);

    void addSound(WorldType world,ModelID id,String soundPath);

    void addMaterial(String matName,Material mat);

    Material getMaterial(String matName);

    Texture getTexture(WorldType world,ModelID id);

    AudioNode getSound(ModelID id,WorldType world);

    Spatial getModel(ModelID id);

    void initSpatials();

    void initMaterials();

    void initSounds();

    void initTextures();



    }

    [/java]

All of this is very implementation specific. Others load their entities and data from a database or scripts where the asset key would be stored differently. Also the implemented material definitions are not a list set in stone, every advanced game will have its own and access them differently.

I dont totailly disagree But i think enums are good because use AutoComplete feature

u can moduify this class to your own enum and modify this to your implemntation



of course u better only use the interface and implemnt it yourself.

i just think the interface makes every project more organized

It’s not a terrible idea. How useful it is will depend a lot on the nature of your project though. If all your assets are fixed and accessed from code then you will be ok.



In my case though a lot of my assets are identified by configuration (i.e. you create objects, the config of those objects says what assets they need, etc). You will find that is the case in a lot of games.



In that case the enum becomes a lot of trouble to manage as each time new art assets are added you need to add them into the enum, and the whole point of being able to add/change stuff without involving programmers falls over.

1 Like

thx for the feedback guys .i will make a new thread for my game when i finish the alpha. i have background in programming but this is my first full game project.

Good luck, and don’t be scared to post ideas and discussion in the forums… :slight_smile: