Optimized Model loader to no longer require vertex duplication
This commit is contained in:
parent
ede8b1d1a1
commit
c95e7ce20d
|
@ -33,8 +33,7 @@ public class Language
|
||||||
|
|
||||||
public String translate(String key)
|
public String translate(String key)
|
||||||
{
|
{
|
||||||
String result = translations.get(key);
|
return translations.getOrDefault(key, key);
|
||||||
return result == null ? key : result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String translate(String key, Object...args)
|
public String translate(String key, Object...args)
|
||||||
|
|
|
@ -9,7 +9,7 @@ import speiger.src.coreengine.rendering.gui.helper.animations.transitions.ITrans
|
||||||
|
|
||||||
public class Animation
|
public class Animation
|
||||||
{
|
{
|
||||||
Object2ObjectMap<AnimationTarget, ITransition> transitions = new Object2ObjectLinkedOpenHashMap<AnimationTarget, ITransition>();
|
Object2ObjectMap<AnimationTarget, ITransition> transitions = new Object2ObjectLinkedOpenHashMap<>();
|
||||||
AnimationListener listener;
|
AnimationListener listener;
|
||||||
float duration = 0F;
|
float duration = 0F;
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ public class Animation
|
||||||
|
|
||||||
public AnimationInstance createInstance(GuiComponent comp, AnimationInstance old, float delay, boolean reverse)
|
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))
|
for(Object2ObjectMap.Entry<AnimationTarget, ITransition> entry : Object2ObjectMaps.fastIterable(transitions))
|
||||||
{
|
{
|
||||||
AnimationTarget target = entry.getKey();
|
AnimationTarget target = entry.getKey();
|
||||||
|
|
|
@ -46,12 +46,9 @@ public class Animator
|
||||||
|
|
||||||
public void update(float particalTicks)
|
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)
|
if(animations.isEmpty() && !changed)
|
||||||
{
|
{
|
||||||
|
@ -84,18 +81,9 @@ public class Animator
|
||||||
|
|
||||||
private void resetValues()
|
private void resetValues()
|
||||||
{
|
{
|
||||||
if(!changed)
|
if(!changed) return;
|
||||||
{
|
if(!owner.hasConstraints()) owner.changeVisibility(1F / visibilityMod).getBox().move(-xMod, -yMod).grow(-widthMod, -heightMod).scale(1F / scaleMod);
|
||||||
return;
|
else owner.changeVisibility(1F / visibilityMod).getBox().scale(1F / scaleMod);
|
||||||
}
|
|
||||||
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;
|
xMod = 0F;
|
||||||
yMod = 0F;
|
yMod = 0F;
|
||||||
widthMod = 0F;
|
widthMod = 0F;
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package speiger.src.coreengine.rendering.models;
|
package speiger.src.coreengine.rendering.models;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
|
||||||
import speiger.src.collections.objects.maps.impl.hash.Object2ObjectOpenHashMap;
|
import speiger.src.collections.objects.maps.impl.hash.Object2ObjectOpenHashMap;
|
||||||
|
import speiger.src.coreengine.rendering.models.loader.VertexLoader.JsonList;
|
||||||
|
|
||||||
public enum DataType
|
public enum DataType
|
||||||
{
|
{
|
||||||
|
@ -40,32 +42,40 @@ public enum DataType
|
||||||
return this == FLOAT || this == DOUBLE;
|
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)
|
switch(this)
|
||||||
{
|
{
|
||||||
case BYTE:
|
case BYTE:
|
||||||
buffer.put(data.byteValue());
|
buffer.put(index, element.getAsByte());
|
||||||
break;
|
break;
|
||||||
case SHORT:
|
case SHORT:
|
||||||
buffer.putShort(data.shortValue());
|
buffer.putShort(index, element.getAsShort());
|
||||||
break;
|
break;
|
||||||
case INT:
|
case INT:
|
||||||
buffer.putInt(data.intValue());
|
buffer.putInt(index, element.getAsInt());
|
||||||
break;
|
break;
|
||||||
case LONG:
|
case LONG:
|
||||||
buffer.putLong(data.longValue());
|
buffer.putLong(index, element.getAsLong());
|
||||||
break;
|
break;
|
||||||
case FLOAT:
|
case FLOAT:
|
||||||
buffer.putFloat(data.floatValue());
|
buffer.putFloat(index, element.getAsFloat());
|
||||||
break;
|
break;
|
||||||
case DOUBLE:
|
case DOUBLE:
|
||||||
buffer.putDouble(data.doubleValue());
|
buffer.putDouble(index, element.getAsDouble());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class ModelCache implements IReloadableResource
|
||||||
{
|
{
|
||||||
if(data.isEmpty())
|
if(data.isEmpty())
|
||||||
{
|
{
|
||||||
System.out.println("["+location+"]Found Empty Model Data");
|
System.out.println("["+location+"] Found Empty Model Data");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
models.put(location, data);
|
models.put(location, data);
|
||||||
|
|
|
@ -57,7 +57,6 @@ public class BufferAttachment implements IFrameAttachment
|
||||||
@Override
|
@Override
|
||||||
public void init(int type, int width, int height, int samples)
|
public void init(int type, int width, int height, int samples)
|
||||||
{
|
{
|
||||||
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.samples = samples;
|
this.samples = samples;
|
||||||
if(id == 0)
|
if(id == 0)
|
||||||
|
|
|
@ -42,6 +42,11 @@ public class VertexEntry
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getByteSize()
|
||||||
|
{
|
||||||
|
return size * glType.getByteSize();
|
||||||
|
}
|
||||||
|
|
||||||
public GLDataType getType()
|
public GLDataType getType()
|
||||||
{
|
{
|
||||||
return glType;
|
return glType;
|
||||||
|
@ -59,7 +64,7 @@ public class VertexEntry
|
||||||
{
|
{
|
||||||
VertexEntry entry = array.get(i);
|
VertexEntry entry = array.get(i);
|
||||||
if(entry.isOptional() && excludeOptional) continue;
|
if(entry.isOptional() && excludeOptional) continue;
|
||||||
result += entry.getSize() * entry.getType().getByteSize();
|
result += entry.getByteSize();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
import speiger.src.collections.objects.lists.ObjectArrayList;
|
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)
|
public static ByteBuffer parseVertexData(JsonObject obj, int vertexCount, List<VertexEntry> entries, boolean excludeOptional)
|
||||||
{
|
{
|
||||||
List<Number> numbers = parseVertexData(obj, entries, excludeOptional);
|
int byteStride = VertexEntry.caculateByteSize(entries, excludeOptional);
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(vertexCount * VertexEntry.caculateByteSize(entries, excludeOptional)).order(ByteOrder.nativeOrder());
|
JsonArray vertexes = obj.getAsJsonArray("vertexes");
|
||||||
for(int i = 0,offset=0,m=vertexCount*entries.size();i<m;i++)
|
ByteBuffer buffer = ByteBuffer.allocate(vertexCount * byteStride).order(ByteOrder.nativeOrder());
|
||||||
{
|
|
||||||
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 stride = VertexEntry.caclulateStride(entries);
|
int stride = VertexEntry.caclulateStride(entries);
|
||||||
int outStride = excludeOptional ? VertexEntry.calculateNonOptionalStride(entries) : stride;
|
for(int i = 0,offset = 0, byteOffset = 0,m=entries.size();i<m;i++)
|
||||||
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++)
|
|
||||||
{
|
{
|
||||||
VertexEntry entry = entries.get(i);
|
VertexEntry entry = entries.get(i);
|
||||||
if(!entry.isOptional() || !excludeOptional)
|
if(!entry.isOptional() || !excludeOptional)
|
||||||
{
|
{
|
||||||
deserializeIndecies(vertexes, JsonUtil.parseArray(obj.getAsJsonArray(entry.getName())), entry.getSize(), stride, inOff, data, outStride, outOff);
|
entry.getType().getDataType().putIntoBuffer(buffer, new JsonWrapper(vertexes, obj.getAsJsonArray(entry.getName()), offset, stride, entry.getSize(), vertexCount), byteOffset, byteStride, entry.getSize());
|
||||||
outOff += 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)
|
public static Object2ObjectMap<String, List<Number>> parseMappedVertexData(JsonObject obj, List<VertexEntry> entries, boolean excludeOptional)
|
||||||
|
@ -66,14 +54,6 @@ public class VertexLoader
|
||||||
return mappedData;
|
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)
|
public static <T> List<T> deserializeIndecies(int[] indecies, T[] in, int size, int stride, int offset)
|
||||||
{
|
{
|
||||||
List<T> out = new ObjectArrayList<>();
|
List<T> out = new ObjectArrayList<>();
|
||||||
|
@ -83,4 +63,43 @@ public class VertexLoader
|
||||||
}
|
}
|
||||||
return out;
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import speiger.src.coreengine.assets.reloader.IReloadableResource;
|
||||||
public class ShaderTracker implements IReloadableResource
|
public class ShaderTracker implements IReloadableResource
|
||||||
{
|
{
|
||||||
public static final ShaderTracker INSTANCE = new ShaderTracker();
|
public static final ShaderTracker INSTANCE = new ShaderTracker();
|
||||||
List<ReloadReference<?>> programs = new ObjectArrayList<ReloadReference<?>>();
|
List<ReloadReference<?>> programs = new ObjectArrayList<>();
|
||||||
int activeShader = 0;
|
int activeShader = 0;
|
||||||
boolean reloading = false;
|
boolean reloading = false;
|
||||||
AssetManager assets;
|
AssetManager assets;
|
||||||
|
@ -27,8 +27,7 @@ public class ShaderTracker implements IReloadableResource
|
||||||
{
|
{
|
||||||
T result = creator.get();
|
T result = creator.get();
|
||||||
result.init();
|
result.init();
|
||||||
ReloadReference<T> reference = new ReloadReference<>(result, creator, reloader);
|
programs.add(new ReloadReference<>(result, creator, reloader));
|
||||||
programs.add(reference);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ public class Listeners
|
||||||
{
|
{
|
||||||
for(int i = 0;i<unsortedListeners.length;i++)
|
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)
|
public void removeListeners(Consumer<Event> listener)
|
||||||
{
|
{
|
||||||
boolean found = false;
|
|
||||||
for(int i = 0,m=unsortedListeners.length;i<m;i++)
|
for(int i = 0,m=unsortedListeners.length;i<m;i++)
|
||||||
{
|
{
|
||||||
if(unsortedListeners[i].remove(listener))
|
if(unsortedListeners[i].remove(listener))
|
||||||
{
|
{
|
||||||
found = true;
|
markDirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(found)
|
|
||||||
{
|
|
||||||
markDirty();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getListeners(EventPriority entry, List<Consumer<Event>> events)
|
public void getListeners(EventPriority entry, List<Consumer<Event>> events)
|
||||||
|
@ -77,6 +72,7 @@ public class Listeners
|
||||||
|
|
||||||
private void markDirty()
|
private void markDirty()
|
||||||
{
|
{
|
||||||
|
if(rebuild) return;
|
||||||
rebuild = true;
|
rebuild = true;
|
||||||
if(childs != null)
|
if(childs != null)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue