[DEV] update palette model to support 3 state by palette

This commit is contained in:
Edouard DUPIN 2021-05-31 21:52:30 +02:00
parent 320be27f8c
commit 3f654df8e3
2 changed files with 79 additions and 55 deletions

View File

@ -460,7 +460,7 @@ void setNormalMode(final NormalMode _mode) {
break; break;
} }
float maxValues = ResourcePaletteFile.getColorMax(); float maxValues = ResourcePaletteFile.getColorMax();
float height = 8.0f; float height = ResourcePaletteFile.getHeight();
int indexColor = ResourcePaletteFile.getColorId(elem.getKey().substring(8)); int indexColor = ResourcePaletteFile.getColorId(elem.getKey().substring(8));
Vector2f texturepos = new Vector2f((indexColor+0.5f)/maxValues, 0.5f/height); Vector2f texturepos = new Vector2f((indexColor+0.5f)/maxValues, 0.5f/height);
Log.error("find color : " + elem.getKey().substring(8) + " ==> " + indexColor + " pos = " + texturepos); Log.error("find color : " + elem.getKey().substring(8) + " ==> " + indexColor + " pos = " + texturepos);

View File

@ -7,48 +7,55 @@ package org.atriasoft.loader3d.resources;
*/ */
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map.Entry;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.Map;
import java.util.Map.Entry;
import org.atriasoft.egami.ImageByte; import org.atriasoft.egami.ImageByte;
import org.atriasoft.egami.ImageByteRGB;
import org.atriasoft.egami.ImageByteRGBA; import org.atriasoft.egami.ImageByteRGBA;
import org.atriasoft.ejson.Ejson; import org.atriasoft.ejson.Ejson;
import org.atriasoft.ejson.model.JsonArray;
import org.atriasoft.ejson.model.JsonNode; import org.atriasoft.ejson.model.JsonNode;
import org.atriasoft.ejson.model.JsonObject; import org.atriasoft.ejson.model.JsonObject;
import org.atriasoft.etk.Color; import org.atriasoft.etk.Color;
import org.atriasoft.etk.Tools;
import org.atriasoft.etk.Uri; import org.atriasoft.etk.Uri;
import org.atriasoft.etk.math.Vector4f; import org.atriasoft.etk.math.Vector4f;
import org.atriasoft.loader3d.internal.Log;
import org.atriasoft.loader3d.model.Material;
import org.atriasoft.loader3d.model.MaterialBase;
import org.atriasoft.gale.resource.Resource; import org.atriasoft.gale.resource.Resource;
import org.atriasoft.loader3d.internal.Log;
import org.atriasoft.loader3d.model.MaterialBase;
/** /**
* ColorFile is a Resource designed to be specific with the theme (for * ColorFile is a Resource designed to be specific with the theme (for
* example black, or white or orange ...) * example black, or white or orange ...)
*/ */
public class ResourcePaletteFile extends Resource { public class ResourcePaletteFile extends Resource {
private static final int COUNT_HEIGHT_PALETTE = 16;
private static final int COUNT_MAX_COLOR_PALETTE = 32; private static final int COUNT_MAX_COLOR_PALETTE = 32;
private static final List<String> PALETTE_ELEMENTS = new ArrayList<>(COUNT_MAX_COLOR_PALETTE); private static final String DEFINE_PALETTE = "palette";
private static final String DEFINE_DEFAULT = "default";
private static final String DEFINE_OVER = "over";
private static final String DEFINE_SELECT = "select";
private static final String DEFINE_SHINESS = "Ns";
private static final String DEFINE_AMBIANT_FACTOR = "Ka";
private static final String DEFINE_SPECULAR_FACTOR = "Ks";
private static final String DEFINE_DIFFUSE_FACTOR = "Kd";
private static final List<String> PALETTE_ELEMENTS = new ArrayList<>(ResourcePaletteFile.COUNT_MAX_COLOR_PALETTE);
static { static {
PALETTE_ELEMENTS.add("unknown"); ResourcePaletteFile.PALETTE_ELEMENTS.add("unknown");
} }
public static synchronized int getColorId(String color) { public static synchronized int getColorId(final String color) {
for (int iii=0; iii<PALETTE_ELEMENTS.size(); iii++) { for (int iii=0; iii<ResourcePaletteFile.PALETTE_ELEMENTS.size(); iii++) {
if (PALETTE_ELEMENTS.get(iii).equals(color)) { if (ResourcePaletteFile.PALETTE_ELEMENTS.get(iii).equals(color)) {
return iii; return iii;
} }
} }
PALETTE_ELEMENTS.add(color); ResourcePaletteFile.PALETTE_ELEMENTS.add(color);
return PALETTE_ELEMENTS.size()-1; return ResourcePaletteFile.PALETTE_ELEMENTS.size()-1;
} }
public static int getColorMax() { public static int getColorMax() {
return COUNT_MAX_COLOR_PALETTE; return ResourcePaletteFile.COUNT_MAX_COLOR_PALETTE;
}
public static int getHeight() {
return ResourcePaletteFile.COUNT_HEIGHT_PALETTE;
} }
private Runnable updatePostAction = null; private Runnable updatePostAction = null;
@ -69,10 +76,12 @@ public class ResourcePaletteFile extends Resource {
return new ResourcePaletteFile(uri); return new ResourcePaletteFile(uri);
} }
private Color errorColor = Color.ORANGE; private final Color errorColor = Color.ORANGE;
private MaterialBase base = new MaterialBase(); private MaterialBase base = new MaterialBase();
private final SortedMap<String, MaterialBase> list = new TreeMap<String, MaterialBase>(); // !< List of all color in the file private final SortedMap<String, MaterialBase> listNormal = new TreeMap<String, MaterialBase>(); // !< List of all color in the file
private final SortedMap<String, MaterialBase> listOver = new TreeMap<String, MaterialBase>(); // !< List of all color in the file
private final SortedMap<String, MaterialBase> listSelect = new TreeMap<String, MaterialBase>(); // !< List of all color in the file
/** /**
* Constructor of the color property file * Constructor of the color property file
@ -99,35 +108,35 @@ public class ResourcePaletteFile extends Resource {
if (id == null) { if (id == null) {
return this.errorColor; return this.errorColor;
} }
Vector4f color = this.list.get(id).getAmbientFactor(); Vector4f color = this.listNormal.get(id).getAmbientFactor();
return new Color(color.x(), color.y(), color.z(), color.w()); return new Color(color.x(), color.y(), color.z(), color.w());
} }
private MaterialBase configMaterial(JsonObject baseDefault) { private MaterialBase configMaterial(final JsonObject node, final MaterialBase parent) {
MaterialBase element = this.base.clone(); MaterialBase element = parent.clone();
try { try {
if (baseDefault != null) { if (node != null) {
if (baseDefault.exist("Ns")) { if (node.exist(ResourcePaletteFile.DEFINE_SHINESS)) {
final double data = baseDefault.get("Ns").toJsonNumber().getValue(); final double data = node.get(ResourcePaletteFile.DEFINE_SHINESS).toJsonNumber().getValue();
Log.verbose(" Shininess " + data); Log.verbose(" Shininess " + data);
element.setShininess((float)data); element.setShininess((float)data);
} }
if (baseDefault.exist("Ka")) { if (node.exist(ResourcePaletteFile.DEFINE_AMBIANT_FACTOR)) {
final String data = baseDefault.get("Ka").toJsonString().getValue(); final String data = node.get(ResourcePaletteFile.DEFINE_AMBIANT_FACTOR).toJsonString().getValue();
Vector4f tmp = Vector4f.valueOf(data); Vector4f tmp = Vector4f.valueOf(data);
tmp = tmp.withW(1); tmp = tmp.withW(1);
Log.verbose(" AmbientFactor " + tmp); Log.verbose(" AmbientFactor " + tmp);
element.setAmbientFactor(tmp); element.setAmbientFactor(tmp);
} }
if (baseDefault.exist("Kd")) { if (node.exist(ResourcePaletteFile.DEFINE_DIFFUSE_FACTOR)) {
final String data = baseDefault.get("Kd").toJsonString().getValue(); final String data = node.get(ResourcePaletteFile.DEFINE_DIFFUSE_FACTOR).toJsonString().getValue();
Vector4f tmp = Vector4f.valueOf(data); Vector4f tmp = Vector4f.valueOf(data);
tmp = tmp.withW(1); tmp = tmp.withW(1);
Log.verbose(" DiffuseFactor " + tmp); Log.verbose(" DiffuseFactor " + tmp);
element.setDiffuseFactor(tmp); element.setDiffuseFactor(tmp);
} }
if (baseDefault.exist("Ks")) { if (node.exist(ResourcePaletteFile.DEFINE_SPECULAR_FACTOR)) {
final String data = baseDefault.get("Ks").toJsonString().getValue(); final String data = node.get(ResourcePaletteFile.DEFINE_SPECULAR_FACTOR).toJsonString().getValue();
Vector4f tmp = Vector4f.valueOf(data); Vector4f tmp = Vector4f.valueOf(data);
tmp = tmp.withW(1); tmp = tmp.withW(1);
Log.verbose(" SpecularFactor " + tmp); Log.verbose(" SpecularFactor " + tmp);
@ -143,23 +152,36 @@ public class ResourcePaletteFile extends Resource {
@Override @Override
public synchronized void reload() { public synchronized void reload() {
this.list.clear(); this.listNormal.clear();
this.base = new MaterialBase(); this.base = new MaterialBase();
try { try {
final JsonObject out = Ejson.parse(Uri.valueOf(this.name)).toJsonObject(); final JsonObject out = Ejson.parse(Uri.valueOf(this.name)).toJsonObject();
final JsonObject baseDefault = out.get("default").toJsonObject(); final JsonObject baseDefault = out.get(ResourcePaletteFile.DEFINE_DEFAULT).toJsonObject();
this.base = configMaterial(baseDefault); this.base = configMaterial(baseDefault, this.base);
final JsonObject baseObject = out.get("palette").toJsonObject(); final JsonObject baseObject = out.get(ResourcePaletteFile.DEFINE_PALETTE).toJsonObject();
if (baseObject == null) { if (baseObject == null) {
Log.error("Can not get basic object : 'palette' in file:" + this.name); Log.error("Can not get basic object : 'palette' in file:" + this.name);
Ejson.display(out); Ejson.display(out);
return; return;
} }
for (Entry<String, JsonNode> it : baseObject.getNodes().entrySet()) { for (Entry<String, JsonNode> it : baseObject.getNodes().entrySet()) {
MaterialBase mat = configMaterial(it.getValue().toJsonObject()); JsonObject nodeMaterial = it.getValue().toJsonObject();
list.put(it.getKey(), mat); MaterialBase mat = configMaterial(nodeMaterial, this.base);
this.listNormal.put(it.getKey(), mat);
if (nodeMaterial.exist(ResourcePaletteFile.DEFINE_OVER)) {
MaterialBase matOver = configMaterial(nodeMaterial.get(ResourcePaletteFile.DEFINE_OVER).toJsonObject(), mat);
this.listOver.put(it.getKey(), matOver);
} else {
this.listOver.put(it.getKey(), mat);
}
if (nodeMaterial.exist(ResourcePaletteFile.DEFINE_SELECT)) {
MaterialBase matSelect = configMaterial(nodeMaterial.get(ResourcePaletteFile.DEFINE_SELECT).toJsonObject(), mat);
this.listSelect.put(it.getKey(), matSelect);
} else {
this.listSelect.put(it.getKey(), mat);
}
} }
} catch (final Exception e) { } catch (final Exception e) {
Log.error("chach exception in parsing config file... " + e.getMessage()); Log.error("chach exception in parsing config file... " + e.getMessage());
@ -172,43 +194,45 @@ public class ResourcePaletteFile extends Resource {
} }
} }
public void onUpdate(Runnable object) { public void onUpdate(final Runnable object) {
this.updatePostAction = object; this.updatePostAction = object;
} }
public ImageByte getImageByte() { public ImageByte getImageByte() {
int width = COUNT_MAX_COLOR_PALETTE; int width = ResourcePaletteFile.COUNT_MAX_COLOR_PALETTE;
int height = 8; int height = ResourcePaletteFile.COUNT_HEIGHT_PALETTE;
ImageByteRGBA out = new ImageByteRGBA(width, height); ImageByteRGBA out = new ImageByteRGBA(width, height);
//ImageByteRGB out = new ImageByteRGB(width, height); //ImageByteRGB out = new ImageByteRGB(width, height);
// clear the palette: // clear the palette:
//float val = 0.0f; //float val = 0.0f;
for (int xxx=0; xxx < width; xxx++) { for (int xxx=0; xxx < width; xxx++) {
for (int yyy=0; yyy < 8; yyy++) { for (int yyy=0; yyy < ResourcePaletteFile.COUNT_HEIGHT_PALETTE; yyy++) {
out.setColorFloat(xxx, yyy, 1, 1, 1, 1); out.setColorFloat(xxx, yyy, 1, 1, 1, 1);
//out.setColorFloat(xxx, yyy, val, val + 0.125f, val + 0.85f, 1); //out.setColorFloat(xxx, yyy, val, val + 0.125f, val + 0.85f, 1);
//val += 0.01f; //val += 0.01f;
} }
} }
for (Entry<String, MaterialBase> it : this.list.entrySet()) { for (Entry<String, MaterialBase> it : this.listNormal.entrySet()) {
int id = getColorId(it.getKey()); int id = ResourcePaletteFile.getColorId(it.getKey());
MaterialBase mat = it.getValue(); MaterialBase mat = it.getValue();
MaterialBase matOver = this.listOver.get(it.getKey());
MaterialBase matSelect = this.listSelect.get(it.getKey());
Log.error("add Material in texture: '" + it.getKey() + "' ==> " + id + " mat=" + mat); Log.error("add Material in texture: '" + it.getKey() + "' ==> " + id + " mat=" + mat);
// 2 element this will permit to change color in the future on depend on some parameters... // 2 element this will permit to change color in the future on depend on some parameters...
out.setColorFloat(id, 0, mat.getDiffuseFactor().x(), mat.getDiffuseFactor().y(), mat.getDiffuseFactor().z(), mat.getDiffuseFactor().w()); putColor(id, 0, out, mat);
out.setColorFloat(id, 1, mat.getDiffuseFactor().x(), mat.getDiffuseFactor().y(), mat.getDiffuseFactor().z(), mat.getDiffuseFactor().w()); putColor(id, 1, out, matOver);
putColor(id, 2, out, matSelect);
out.setColorFloat(id, 2, mat.getSpecularFactor().x(), mat.getSpecularFactor().y(), mat.getSpecularFactor().z(), mat.getSpecularFactor().w()); putColor(id, 3, out, mat);
out.setColorFloat(id, 3, mat.getSpecularFactor().x(), mat.getSpecularFactor().y(), mat.getSpecularFactor().z(), mat.getSpecularFactor().w()); // Note: this model permit to have interpolation of color normal <-> over ; normal <-> select ; over <-> select
out.setColorFloat(id, 4, mat.getAmbientFactor().x(), mat.getAmbientFactor().y(), mat.getAmbientFactor().z(), mat.getAmbientFactor().w());
out.setColorFloat(id, 5, mat.getAmbientFactor().x(), mat.getAmbientFactor().y(), mat.getAmbientFactor().z(), mat.getAmbientFactor().w());
out.setColorFloat(id, 6, mat.getShininess(), 1.0f, 1.0f, 1.0f);
} }
return out; return out;
} }
private void putColor(final int index, final int offset, final ImageByte image, final MaterialBase mat) {
image.setColorFloat(index, 0+offset, mat.getDiffuseFactor().x(), mat.getDiffuseFactor().y(), mat.getDiffuseFactor().z(), mat.getDiffuseFactor().w());
image.setColorFloat(index, 4+offset, mat.getSpecularFactor().x(), mat.getSpecularFactor().y(), mat.getSpecularFactor().z(), mat.getSpecularFactor().w());
image.setColorFloat(index, 8+offset, mat.getAmbientFactor().x(), mat.getAmbientFactor().y(), mat.getAmbientFactor().z(), mat.getAmbientFactor().w());
image.setColorFloat(index, 12+offset, mat.getShininess(), 1.0f, 1.0f, 1.0f);
}
} }