Optimized Model loader to no longer require vertex duplication

This commit is contained in:
Speiger 2022-04-24 21:55:05 +02:00
parent ede8b1d1a1
commit c95e7ce20d
10 changed files with 89 additions and 74 deletions

View File

@ -33,8 +33,7 @@ public class Language
public String translate(String key)
{
String result = translations.get(key);
return result == null ? key : result;
return translations.getOrDefault(key, key);
}
public String translate(String key, Object...args)

View File

@ -9,7 +9,7 @@ import speiger.src.coreengine.rendering.gui.helper.animations.transitions.ITrans
public class Animation
{
Object2ObjectMap<AnimationTarget, ITransition> transitions = new Object2ObjectLinkedOpenHashMap<AnimationTarget, ITransition>();
Object2ObjectMap<AnimationTarget, ITransition> transitions = new Object2ObjectLinkedOpenHashMap<>();
AnimationListener listener;
float duration = 0F;
@ -28,7 +28,7 @@ public class Animation
public AnimationInstance createInstance(GuiComponent comp, AnimationInstance old, float delay, boolean reverse)
{
Object2ObjectMap<AnimationTarget, IValue> values = new Object2ObjectLinkedOpenHashMap<AnimationTarget, IValue>();
Object2ObjectMap<AnimationTarget, IValue> values = new Object2ObjectLinkedOpenHashMap<>();
for(Object2ObjectMap.Entry<AnimationTarget, ITransition> entry : Object2ObjectMaps.fastIterable(transitions))
{
AnimationTarget target = entry.getKey();

View File

@ -46,12 +46,9 @@ public class Animator
public void update(float particalTicks)
{
if(listeners.size() > 0)
for(int i = 0,m=listeners.size();i<m;i++)
{
for(int i = 0,m=listeners.size();i<m;i++)
{
listeners.get(i).accept(owner, this);
}
listeners.get(i).accept(owner, this);
}
if(animations.isEmpty() && !changed)
{
@ -84,18 +81,9 @@ public class Animator
private void resetValues()
{
if(!changed)
{
return;
}
if(!owner.hasConstraints())
{
owner.changeVisibility(1F / visibilityMod).getBox().move(-xMod, -yMod).grow(-widthMod, -heightMod).scale(1F / scaleMod);
}
else
{
owner.changeVisibility(1F / visibilityMod).getBox().scale(1F / scaleMod);
}
if(!changed) return;
if(!owner.hasConstraints()) owner.changeVisibility(1F / visibilityMod).getBox().move(-xMod, -yMod).grow(-widthMod, -heightMod).scale(1F / scaleMod);
else owner.changeVisibility(1F / visibilityMod).getBox().scale(1F / scaleMod);
xMod = 0F;
yMod = 0F;
widthMod = 0F;

View File

@ -1,10 +1,12 @@
package speiger.src.coreengine.rendering.models;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import com.google.gson.JsonElement;
import speiger.src.collections.objects.maps.impl.hash.Object2ObjectOpenHashMap;
import speiger.src.coreengine.rendering.models.loader.VertexLoader.JsonList;
public enum DataType
{
@ -40,32 +42,40 @@ public enum DataType
return this == FLOAT || this == DOUBLE;
}
public void putIntoBuffer(ByteBuffer buffer, List<Number> data, int offset, int size)
public void putIntoBuffer(ByteBuffer buffer, JsonList list, int offset, int stride, int size)
{
for(int i = 0;i<size;putIntoBuffer(buffer, data.get(offset+i)),i++);
int index = offset;
for(int i = 0,m=list.size();i<m;)
{
putIntoBuffer(buffer, index, list.get(i));
index += byteSize;
if(++i % size == 0) {
index+=stride;
}
}
}
public void putIntoBuffer(ByteBuffer buffer, Number data)
public void putIntoBuffer(ByteBuffer buffer, int index, JsonElement element)
{
switch(this)
{
case BYTE:
buffer.put(data.byteValue());
buffer.put(index, element.getAsByte());
break;
case SHORT:
buffer.putShort(data.shortValue());
buffer.putShort(index, element.getAsShort());
break;
case INT:
buffer.putInt(data.intValue());
buffer.putInt(index, element.getAsInt());
break;
case LONG:
buffer.putLong(data.longValue());
buffer.putLong(index, element.getAsLong());
break;
case FLOAT:
buffer.putFloat(data.floatValue());
buffer.putFloat(index, element.getAsFloat());
break;
case DOUBLE:
buffer.putDouble(data.doubleValue());
buffer.putDouble(index, element.getAsDouble());
break;
}
}

View File

@ -47,7 +47,7 @@ public class ModelCache implements IReloadableResource
{
if(data.isEmpty())
{
System.out.println("["+location+"]Found Empty Model Data");
System.out.println("["+location+"] Found Empty Model Data");
return;
}
models.put(location, data);

View File

@ -57,7 +57,6 @@ public class BufferAttachment implements IFrameAttachment
@Override
public void init(int type, int width, int height, int samples)
{
this.type = type;
this.samples = samples;
if(id == 0)

View File

@ -42,6 +42,11 @@ public class VertexEntry
return size;
}
public int getByteSize()
{
return size * glType.getByteSize();
}
public GLDataType getType()
{
return glType;
@ -59,7 +64,7 @@ public class VertexEntry
{
VertexEntry entry = array.get(i);
if(entry.isOptional() && excludeOptional) continue;
result += entry.getSize() * entry.getType().getByteSize();
result += entry.getByteSize();
}
return result;
}

View File

@ -4,6 +4,8 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.List;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import speiger.src.collections.objects.lists.ObjectArrayList;
@ -21,35 +23,21 @@ public class VertexLoader
public static ByteBuffer parseVertexData(JsonObject obj, int vertexCount, List<VertexEntry> entries, boolean excludeOptional)
{
List<Number> numbers = parseVertexData(obj, entries, excludeOptional);
ByteBuffer buffer = ByteBuffer.allocate(vertexCount * VertexEntry.caculateByteSize(entries, excludeOptional)).order(ByteOrder.nativeOrder());
for(int i = 0,offset=0,m=vertexCount*entries.size();i<m;i++)
{
VertexEntry entry = entries.get(i % entries.size());
if(entry.isOptional() && excludeOptional) continue;
entry.getType().getDataType().putIntoBuffer(buffer, numbers, offset, entry.getSize());
offset+=entry.getSize();
}
return buffer;
}
public static List<Number> parseVertexData(JsonObject obj, List<VertexEntry> entries, boolean excludeOptional)
{
int byteStride = VertexEntry.caculateByteSize(entries, excludeOptional);
JsonArray vertexes = obj.getAsJsonArray("vertexes");
ByteBuffer buffer = ByteBuffer.allocate(vertexCount * byteStride).order(ByteOrder.nativeOrder());
int stride = VertexEntry.caclulateStride(entries);
int outStride = excludeOptional ? VertexEntry.calculateNonOptionalStride(entries) : stride;
int[] vertexes = JsonUtil.parseIntArray(obj.getAsJsonArray("vertexes"));
Number[] data = new Number[excludeOptional ? (vertexes.length / stride) * outStride : vertexes.length];
for(int i = 0,inOff=0,outOff=0,m=entries.size();i<m;i++)
for(int i = 0,offset = 0, byteOffset = 0,m=entries.size();i<m;i++)
{
VertexEntry entry = entries.get(i);
if(!entry.isOptional() || !excludeOptional)
{
deserializeIndecies(vertexes, JsonUtil.parseArray(obj.getAsJsonArray(entry.getName())), entry.getSize(), stride, inOff, data, outStride, outOff);
outOff += entry.getSize();
entry.getType().getDataType().putIntoBuffer(buffer, new JsonWrapper(vertexes, obj.getAsJsonArray(entry.getName()), offset, stride, entry.getSize(), vertexCount), byteOffset, byteStride, entry.getSize());
byteOffset += entry.getByteSize();
}
inOff += entry.getSize();
offset += entry.getSize();
}
return ObjectArrayList.wrap(data);
return buffer;
}
public static Object2ObjectMap<String, List<Number>> parseMappedVertexData(JsonObject obj, List<VertexEntry> entries, boolean excludeOptional)
@ -66,14 +54,6 @@ public class VertexLoader
return mappedData;
}
public static <T> void deserializeIndecies(int[] indecies, T[] in, int size, int stride, int offset, T[] out, int outStride, int outOffset)
{
for(int i = 0,m=(indecies.length/stride)*size;i<m;i++)
{
out[outOffset + ((i/size) * outStride) + (i % size)] = in[indecies[offset + ((i/size) * stride) + (i % size)]];
}
}
public static <T> List<T> deserializeIndecies(int[] indecies, T[] in, int size, int stride, int offset)
{
List<T> out = new ObjectArrayList<>();
@ -83,4 +63,43 @@ public class VertexLoader
}
return out;
}
public static interface JsonList
{
public JsonElement get(int index);
public int size();
}
private static class JsonWrapper implements JsonList
{
JsonArray array;
JsonArray vertexes;
int offset;
int size;
int stride;
int max;
public JsonWrapper(JsonArray vertexes, JsonArray array, int offset, int stride, int size, int max)
{
this.array = array;
this.vertexes = vertexes;
this.offset = offset;
this.size = size;
this.stride = stride;
this.max = max;
}
@Override
public int size()
{
return max;
}
@Override
public JsonElement get(int index)
{
return array.get(vertexes.get(offset + ((index/size) * stride) + (index % size)).getAsInt());
}
}
}

View File

@ -13,7 +13,7 @@ import speiger.src.coreengine.assets.reloader.IReloadableResource;
public class ShaderTracker implements IReloadableResource
{
public static final ShaderTracker INSTANCE = new ShaderTracker();
List<ReloadReference<?>> programs = new ObjectArrayList<ReloadReference<?>>();
List<ReloadReference<?>> programs = new ObjectArrayList<>();
int activeShader = 0;
boolean reloading = false;
AssetManager assets;
@ -27,8 +27,7 @@ public class ShaderTracker implements IReloadableResource
{
T result = creator.get();
result.init();
ReloadReference<T> reference = new ReloadReference<>(result, creator, reloader);
programs.add(reference);
programs.add(new ReloadReference<>(result, creator, reloader));
return result;
}

View File

@ -19,7 +19,7 @@ public class Listeners
{
for(int i = 0;i<unsortedListeners.length;i++)
{
unsortedListeners[i] = new ObjectLinkedOpenHashSet<Consumer<Event>>();
unsortedListeners[i] = new ObjectLinkedOpenHashSet<>();
}
}
@ -46,18 +46,13 @@ public class Listeners
public void removeListeners(Consumer<Event> listener)
{
boolean found = false;
for(int i = 0,m=unsortedListeners.length;i<m;i++)
{
if(unsortedListeners[i].remove(listener))
{
found = true;
markDirty();
}
}
if(found)
{
markDirty();
}
}
public void getListeners(EventPriority entry, List<Consumer<Event>> events)
@ -77,6 +72,7 @@ public class Listeners
private void markDirty()
{
if(rebuild) return;
rebuild = true;
if(childs != null)
{