commit f1722f67553042159c3729d47b9570a73fe15a91 Author: Edouard DUPIN Date: Mon May 3 17:01:35 2021 +0200 [DEV] initial install diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..d1f4d0c --- /dev/null +++ b/.classpath @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..6878643 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + loader3d + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..f11e379 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +External loader of 3D model +=========================== + + +Licence MPL-2 + + diff --git a/src/module-info.java b/src/module-info.java new file mode 100644 index 0000000..9487b8c --- /dev/null +++ b/src/module-info.java @@ -0,0 +1,10 @@ + +module org.atriasoft.loader3d { + + exports org.atriasoft.loader3d; + exports org.atriasoft.loader3d.model; + exports org.atriasoft.loader3d.resources; + + requires transitive org.atriasoft.etk; + requires transitive org.atriasoft.gale; +} \ No newline at end of file diff --git a/src/org/atriasoft/loader3d/Loader3d.java b/src/org/atriasoft/loader3d/Loader3d.java new file mode 100644 index 0000000..3a81544 --- /dev/null +++ b/src/org/atriasoft/loader3d/Loader3d.java @@ -0,0 +1,11 @@ +package org.atriasoft.loader3d; + +public class Loader3d { + /* + public static RawModel loadObjModel(final Uri fileName, final Loader loader) { + System.out.println("Load file " + fileName); + final ModelData data = OBJFileLoader.loadOBJ(fileName); + return loader.loadToVAO(data.getVertices(), data.getTextureCoords(), data.getNormals(), data.getIndices()); + } + */ +} diff --git a/src/org/atriasoft/loader3d/OBJFileLoader.java b/src/org/atriasoft/loader3d/OBJFileLoader.java new file mode 100644 index 0000000..7df6572 --- /dev/null +++ b/src/org/atriasoft/loader3d/OBJFileLoader.java @@ -0,0 +1,166 @@ +package org.atriasoft.loader3d; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; + +import org.atriasoft.etk.Uri; +import org.atriasoft.etk.math.Vector2f; +import org.atriasoft.etk.math.Vector3f; +import org.atriasoft.loader3d.internal.Log; +import org.atriasoft.loader3d.model.ModelData; +import org.atriasoft.loader3d.model.Vertex; + +public class OBJFileLoader { + private static float convertDataToArrays(final List vertices, final List textures, final List normals, final float[] verticesArray, final float[] texturesArray, + final float[] normalsArray) { + float furthestPoint = 0; + for (int i = 0; i < vertices.size(); i++) { + final Vertex currentVertex = vertices.get(i); + if (currentVertex.getLength() > furthestPoint) { + furthestPoint = currentVertex.getLength(); + } + final Vector3f position = currentVertex.getPosition(); + final Vector2f textureCoord = textures.get(currentVertex.getTextureIndex()); + final Vector3f normalVector = normals.get(currentVertex.getNormalIndex()); + verticesArray[i * 3] = position.x(); + verticesArray[i * 3 + 1] = position.y(); + verticesArray[i * 3 + 2] = position.z(); + texturesArray[i * 2] = textureCoord.x(); + texturesArray[i * 2 + 1] = 1 - textureCoord.y(); + normalsArray[i * 3] = normalVector.x(); + normalsArray[i * 3 + 1] = normalVector.y(); + normalsArray[i * 3 + 2] = normalVector.z(); + } + return furthestPoint; + } + + private static int[] convertIndicesListToArray(final List indices) { + final int[] indicesArray = new int[indices.size()]; + for (int i = 0; i < indicesArray.length; i++) { + indicesArray[i] = indices.get(i); + } + return indicesArray; + } + + private static void dealWithAlreadyProcessedVertex(final Vertex previousVertex, final int newTextureIndex, final int newNormalIndex, final List indices, final List vertices) { + if (previousVertex.hasSameTextureAndNormal(newTextureIndex, newNormalIndex)) { + indices.add(previousVertex.getIndex()); + } else { + final Vertex anotherVertex = previousVertex.getDuplicateVertex(); + if (anotherVertex != null) { + OBJFileLoader.dealWithAlreadyProcessedVertex(anotherVertex, newTextureIndex, newNormalIndex, indices, vertices); + } else { + final Vertex duplicateVertex = new Vertex(vertices.size(), previousVertex.getPosition()); + duplicateVertex.setTextureIndex(newTextureIndex); + duplicateVertex.setNormalIndex(newNormalIndex); + previousVertex.setDuplicateVertex(duplicateVertex); + vertices.add(duplicateVertex); + indices.add(duplicateVertex.getIndex()); + } + + } + } + + public static ModelData loadOBJ(final Uri objFileName) { + final InputStream stream = Uri.getStream(objFileName); + if (stream == null) { + Log.error("Can not read file: " + objFileName + " ==> load OBJ"); + return null; + } + /* + final FileReader isr = null; + final File objFile = new File(objFileName); + try { + isr = new FileReader(objFile); + } catch (final FileNotFoundException e) { + System.err.println("File not found in res; don't use any extention"); + return null; + } + */ + BufferedReader reader; + try { + reader = new BufferedReader(new InputStreamReader(stream, "UTF-8")); + } catch (final UnsupportedEncodingException e1) { + Log.error("Error in loading file: " + objFileName + " ==> load OBJ"); + e1.printStackTrace(); + return null; + } + String line; + final List vertices = new ArrayList<>(); + final List textures = new ArrayList<>(); + final List normals = new ArrayList<>(); + final List indices = new ArrayList<>(); + try { + while (true) { + line = reader.readLine(); + if (line.startsWith("v ")) { + final String[] currentLine = line.split(" "); + final Vector3f vertex = new Vector3f(Float.parseFloat(currentLine[1]), Float.parseFloat(currentLine[2]), Float.parseFloat(currentLine[3])); + final Vertex newVertex = new Vertex(vertices.size(), vertex); + vertices.add(newVertex); + + } else if (line.startsWith("vt ")) { + final String[] currentLine = line.split(" "); + final Vector2f texture = new Vector2f(Float.parseFloat(currentLine[1]), Float.parseFloat(currentLine[2])); + textures.add(texture); + } else if (line.startsWith("vn ")) { + final String[] currentLine = line.split(" "); + final Vector3f normal = new Vector3f(Float.parseFloat(currentLine[1]), Float.parseFloat(currentLine[2]), Float.parseFloat(currentLine[3])); + normals.add(normal); + } else if (line.startsWith("f ")) { + break; + } + } + while (line != null && line.startsWith("f ")) { + final String[] currentLine = line.split(" "); + final String[] vertex1 = currentLine[1].split("/"); + final String[] vertex2 = currentLine[2].split("/"); + final String[] vertex3 = currentLine[3].split("/"); + OBJFileLoader.processVertex(vertex1, vertices, indices); + OBJFileLoader.processVertex(vertex2, vertices, indices); + OBJFileLoader.processVertex(vertex3, vertices, indices); + line = reader.readLine(); + } + reader.close(); + } catch (final IOException e) { + System.err.println("Error reading the file"); + } + OBJFileLoader.removeUnusedVertices(vertices); + final float[] verticesArray = new float[vertices.size() * 3]; + final float[] texturesArray = new float[vertices.size() * 2]; + final float[] normalsArray = new float[vertices.size() * 3]; + final float furthest = OBJFileLoader.convertDataToArrays(vertices, textures, normals, verticesArray, texturesArray, normalsArray); + final int[] indicesArray = OBJFileLoader.convertIndicesListToArray(indices); + final ModelData data = new ModelData(verticesArray, texturesArray, normalsArray, indicesArray, furthest); + return data; + } + + private static void processVertex(final String[] vertex, final List vertices, final List indices) { + final int index = Integer.parseInt(vertex[0]) - 1; + final Vertex currentVertex = vertices.get(index); + final int textureIndex = Integer.parseInt(vertex[1]) - 1; + final int normalIndex = Integer.parseInt(vertex[2]) - 1; + if (!currentVertex.isSet()) { + currentVertex.setTextureIndex(textureIndex); + currentVertex.setNormalIndex(normalIndex); + indices.add(index); + } else { + OBJFileLoader.dealWithAlreadyProcessedVertex(currentVertex, textureIndex, normalIndex, indices, vertices); + } + } + + private static void removeUnusedVertices(final List vertices) { + for (final Vertex vertex : vertices) { + if (!vertex.isSet()) { + vertex.setTextureIndex(0); + vertex.setNormalIndex(0); + } + } + } + +} \ No newline at end of file diff --git a/src/org/atriasoft/loader3d/internal/Log.java b/src/org/atriasoft/loader3d/internal/Log.java new file mode 100644 index 0000000..2af58f7 --- /dev/null +++ b/src/org/atriasoft/loader3d/internal/Log.java @@ -0,0 +1,68 @@ +package org.atriasoft.loader3d.internal; + +import io.scenarium.logger.LogLevel; +import io.scenarium.logger.Logger; + +public class Log { + private static final String LIB_NAME = "loader3d"; + private static final String LIB_NAME_DRAW = Logger.getDrawableName(Log.LIB_NAME); + private static final boolean PRINT_CRITICAL = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.CRITICAL); + private static final boolean PRINT_DEBUG = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.DEBUG); + private static final boolean PRINT_ERROR = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.ERROR); + private static final boolean PRINT_INFO = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.INFO); + private static final boolean PRINT_PRINT = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.PRINT); + private static final boolean PRINT_TODO = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.TODO); + private static final boolean PRINT_VERBOSE = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.VERBOSE); + private static final boolean PRINT_WARNING = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.WARNING); + + public static void critical(final String data) { + if (Log.PRINT_CRITICAL) { + Logger.critical(Log.LIB_NAME_DRAW, data); + } + } + + public static void debug(final String data) { + if (Log.PRINT_DEBUG) { + Logger.debug(Log.LIB_NAME_DRAW, data); + } + } + + public static void error(final String data) { + if (Log.PRINT_ERROR) { + Logger.error(Log.LIB_NAME_DRAW, data); + } + } + + public static void info(final String data) { + if (Log.PRINT_INFO) { + Logger.info(Log.LIB_NAME_DRAW, data); + } + } + + public static void print(final String data) { + if (Log.PRINT_PRINT) { + Logger.print(Log.LIB_NAME_DRAW, data); + } + } + + public static void todo(final String data) { + if (Log.PRINT_TODO) { + Logger.todo(Log.LIB_NAME_DRAW, data); + } + } + + public static void verbose(final String data) { + if (Log.PRINT_VERBOSE) { + Logger.verbose(Log.LIB_NAME_DRAW, data); + } + } + + public static void warning(final String data) { + if (Log.PRINT_WARNING) { + Logger.warning(Log.LIB_NAME_DRAW, data); + } + } + + private Log() {} + +} diff --git a/src/org/atriasoft/loader3d/model/ModelData.java b/src/org/atriasoft/loader3d/model/ModelData.java new file mode 100644 index 0000000..6d46cda --- /dev/null +++ b/src/org/atriasoft/loader3d/model/ModelData.java @@ -0,0 +1,10 @@ +package org.atriasoft.loader3d.model; + +public record ModelData( + float[] vertices, + float[] textureCoords, + float[] normals, + int[] indices, + float furthestPoint) { + +} diff --git a/src/org/atriasoft/loader3d/model/Vertex.java b/src/org/atriasoft/loader3d/model/Vertex.java new file mode 100644 index 0000000..90117b1 --- /dev/null +++ b/src/org/atriasoft/loader3d/model/Vertex.java @@ -0,0 +1,66 @@ +package org.atriasoft.loader3d.model; + +import org.atriasoft.etk.math.Vector3f; + +public class Vertex { + + private static final int NO_INDEX = -1; + + private Vector3f position; + private int textureIndex = NO_INDEX; + private int normalIndex = NO_INDEX; + private Vertex duplicateVertex = null; + private int index; + private float length; + + public Vertex(int index,Vector3f position){ + this.index = index; + this.position = position; + this.length = position.length(); + } + + public int getIndex(){ + return index; + } + + public float getLength(){ + return length; + } + + public boolean isSet(){ + return textureIndex!=NO_INDEX && normalIndex!=NO_INDEX; + } + + public boolean hasSameTextureAndNormal(int textureIndexOther,int normalIndexOther){ + return textureIndexOther==textureIndex && normalIndexOther==normalIndex; + } + + public void setTextureIndex(int textureIndex){ + this.textureIndex = textureIndex; + } + + public void setNormalIndex(int normalIndex){ + this.normalIndex = normalIndex; + } + + public Vector3f getPosition() { + return position; + } + + public int getTextureIndex() { + return textureIndex; + } + + public int getNormalIndex() { + return normalIndex; + } + + public Vertex getDuplicateVertex() { + return duplicateVertex; + } + + public void setDuplicateVertex(Vertex duplicateVertex) { + this.duplicateVertex = duplicateVertex; + } + +} diff --git a/src/org/atriasoft/loader3d/resources/ResourceListTexturedMesh.java b/src/org/atriasoft/loader3d/resources/ResourceListTexturedMesh.java new file mode 100644 index 0000000..71425d4 --- /dev/null +++ b/src/org/atriasoft/loader3d/resources/ResourceListTexturedMesh.java @@ -0,0 +1,112 @@ +package org.atriasoft.loader3d.resources; + +import java.util.ArrayList; +import java.util.List; + +import org.atriasoft.etk.Uri; +import org.atriasoft.etk.math.Vector2f; +import org.atriasoft.etk.math.Vector3f; +import org.atriasoft.gale.backend3d.OpenGL.RenderMode; +import org.atriasoft.gale.resource.ResourceVirtualArrayObject; + +public class ResourceListTexturedMesh extends ResourceStaticMesh { + public static ResourceListTexturedMesh create(final RenderMode mode) { + ResourceListTexturedMesh resource = new ResourceListTexturedMesh(mode); + getManager().localAdd(resource); + return resource; + } + + protected List vertices = new ArrayList<>(); + protected List textureCoords = new ArrayList<>(); + protected List normals = new ArrayList<>(); + + protected List indices = new ArrayList<>(); + + protected ResourceListTexturedMesh(final RenderMode mode) { + super(mode); + } + + protected ResourceListTexturedMesh(final Uri uriFile) { + super(uriFile); + } + + public void addQuad(final Vector3f v1, final Vector3f v2, final Vector3f v3, final Vector3f v4, final Vector2f t1, final Vector2f t2, final Vector2f t3, final Vector2f t4, final Vector3f n1) { + addTriangle(v1, v2, v3, t1, t2, t3, n1, n1, n1); + addTriangle(v1, v3, v4, t1, t3, t4, n1, n1, n1); + } + + public void addQuad(final Vector3f v1, final Vector3f v2, final Vector3f v3, final Vector3f v4, final Vector2f t1, final Vector2f t2, final Vector2f t3, final Vector2f t4, final Vector3f n1, + final Vector3f n2, final Vector3f n3, final Vector3f n4) { + addTriangle(v1, v2, v3, t1, t2, t3, n1, n2, n3); + addTriangle(v1, v3, v4, t1, t3, t4, n1, n3, n4); + } + + public void addTriangle(final Vector3f v1, final Vector3f v2, final Vector3f v3, final Vector2f t1, final Vector2f t2, final Vector2f t3, final Vector3f n1, final Vector3f n2, final Vector3f n3) { + this.vertices.add(v1); + this.vertices.add(v2); + this.vertices.add(v3); + this.textureCoords.add(t1); + this.textureCoords.add(t2); + this.textureCoords.add(t3); + this.normals.add(n1); + this.normals.add(n2); + this.normals.add(n3); + this.indices.add(this.vertices.size() - 3); + this.indices.add(this.vertices.size() - 2); + this.indices.add(this.vertices.size() - 1); + } + + public void clear() { + this.vertices.clear(); + this.textureCoords.clear(); + this.normals.clear(); + this.indices.clear(); + } + + /** + * Send the data to the graphic card. + */ + public void flush() { + // request to the manager to be call at the next update ... + this.vao = ResourceVirtualArrayObject.create(toFloatV3(this.vertices), toFloatV2(this.textureCoords), toFloatV3(this.normals), toIntArray(this.indices)); + this.vao.flush(); + } + + private float[] toFloatArray(final List values) { + float[] out = new float[values.size()]; + for (int iii = 0; iii < values.size(); iii++) { + out[iii] = values.get(iii); + } + return out; + } + + private float[] toFloatV2(final List values) { + float[] out = new float[values.size() * 2]; + for (int iii = 0; iii < values.size(); iii++) { + Vector2f tmp = values.get(iii); + out[iii * 2] = tmp.x(); + out[iii * 2 + 1] = tmp.y(); + } + return out; + } + + private float[] toFloatV3(final List values) { + float[] out = new float[values.size() * 3]; + for (int iii = 0; iii < values.size(); iii++) { + Vector3f tmp = values.get(iii); + out[iii * 3] = tmp.x(); + out[iii * 3 + 1] = tmp.y(); + out[iii * 3 + 2] = tmp.z(); + } + return out; + } + + private int[] toIntArray(final List values) { + int[] out = new int[values.size()]; + for (int iii = 0; iii < values.size(); iii++) { + out[iii] = values.get(iii); + } + return out; + } + +} diff --git a/src/org/atriasoft/loader3d/resources/ResourceStaticColoredMesh.java b/src/org/atriasoft/loader3d/resources/ResourceStaticColoredMesh.java new file mode 100644 index 0000000..4a1c069 --- /dev/null +++ b/src/org/atriasoft/loader3d/resources/ResourceStaticColoredMesh.java @@ -0,0 +1,42 @@ +package org.atriasoft.loader3d.resources; + +import org.atriasoft.etk.Uri; +import org.atriasoft.gale.backend3d.OpenGL.RenderMode; +import org.atriasoft.gale.resource.ResourceVirtualArrayObject; + +public class ResourceStaticColoredMesh extends ResourceStaticMesh { + public static ResourceStaticColoredMesh create(final float[] vertices, final float[] colors, final float[] normals, final int[] indices, final RenderMode mode) { + ResourceStaticColoredMesh resource = new ResourceStaticColoredMesh(vertices, colors, normals, indices, mode); + getManager().localAdd(resource); + return resource; + } + + protected float[] vertices = null; + protected float[] colors = null; + protected float[] normals = null; + + protected int[] indices = null; + + protected ResourceStaticColoredMesh(final float[] vertices, final float[] colors, final float[] normals, final int[] indices, final RenderMode mode) { + super(mode); + this.vertices = vertices; + this.colors = colors; + this.normals = normals; + this.indices = indices; + flush(); + } + + protected ResourceStaticColoredMesh(final Uri uriFile) { + super(uriFile); + } + + /** + * Send the data to the graphic card. + */ + public void flush() { + // request to the manager to be call at the next update ... + this.vao = ResourceVirtualArrayObject.create(this.vertices, this.colors, null, this.normals, this.indices); + this.vao.flush(); + } + +} diff --git a/src/org/atriasoft/loader3d/resources/ResourceStaticMesh.java b/src/org/atriasoft/loader3d/resources/ResourceStaticMesh.java new file mode 100644 index 0000000..be566d2 --- /dev/null +++ b/src/org/atriasoft/loader3d/resources/ResourceStaticMesh.java @@ -0,0 +1,54 @@ +package org.atriasoft.loader3d.resources; + +import org.atriasoft.etk.Uri; +import org.atriasoft.gale.backend3d.OpenGL.RenderMode; +import org.atriasoft.gale.resource.Resource; +import org.atriasoft.gale.resource.ResourceVirtualArrayObject; + +public class ResourceStaticMesh extends Resource { + protected RenderMode mode = RenderMode.quadStrip; + protected ResourceVirtualArrayObject vao = null; + + protected ResourceStaticMesh(final RenderMode mode) { + this.mode = mode; + } + + protected ResourceStaticMesh(final Uri uriFile) { + super(uriFile); + } + + public void bindForRendering() { + if (this.vao == null) { + return; + } + this.vao.bindForRendering(); + } + + @Override + public void cleanUp() { + this.vao.cleanUp(); + } + + public RenderMode getMode() { + return this.mode; + } + + public void render() { + if (this.vao == null) { + return; + } + this.vao.render(this.mode); + } + + public void setMode(final RenderMode mode) { + this.mode = mode; + } + + public void unBindForRendering() { + if (this.vao == null) { + return; + } + this.vao.unBindForRendering(); + } + +} diff --git a/src/org/atriasoft/loader3d/resources/ResourceStaticMeshObj.java b/src/org/atriasoft/loader3d/resources/ResourceStaticMeshObj.java new file mode 100644 index 0000000..5fc9c9b --- /dev/null +++ b/src/org/atriasoft/loader3d/resources/ResourceStaticMeshObj.java @@ -0,0 +1,52 @@ +package org.atriasoft.loader3d.resources; + +import org.atriasoft.etk.Uri; +import org.atriasoft.gale.backend3d.OpenGL.RenderMode; +import org.atriasoft.gale.resource.Resource; +import org.atriasoft.loader3d.OBJFileLoader; +import org.atriasoft.loader3d.internal.Log; +import org.atriasoft.loader3d.model.ModelData; + +public class ResourceStaticMeshObj extends ResourceStaticTexturedMesh { + public static ResourceStaticMeshObj create(final Uri uriObj) { + ResourceStaticMeshObj resource; + Resource resource2; + final String name = uriObj.getValue(); + if (name.isEmpty() || name.equals("---")) { + Log.error("Can not create a shader without a filaname"); + return null; + } + resource2 = Resource.getManager().localKeep(name); + if (resource2 != null) { + if (resource2 instanceof ResourceStaticMeshObj) { + resource2.keep(); + return (ResourceStaticMeshObj) resource2; + } + Log.critical("Request resource file : '" + name + "' With the wrong type (dynamic cast error)"); + return null; + } + resource = new ResourceStaticMeshObj(uriObj); + Resource.getManager().localAdd(resource); + return resource; + } + + private final Uri uriFile; + + public ResourceStaticMeshObj(final Uri uriFile) { + super(uriFile); + this.uriFile = uriFile; + System.out.println("Load file " + uriFile); + final ModelData data = OBJFileLoader.loadOBJ(uriFile); + + this.vertices = data.vertices(); + this.textureCoords = data.textureCoords(); + this.normals = data.normals(); + this.indices = data.indices(); + this.mode = RenderMode.triangle; + flush(); + } + + public Uri getUriFile() { + return this.uriFile; + } +} diff --git a/src/org/atriasoft/loader3d/resources/ResourceStaticMeshObjBynamic.java b/src/org/atriasoft/loader3d/resources/ResourceStaticMeshObjBynamic.java new file mode 100644 index 0000000..5a8dd47 --- /dev/null +++ b/src/org/atriasoft/loader3d/resources/ResourceStaticMeshObjBynamic.java @@ -0,0 +1,64 @@ +package org.atriasoft.loader3d.resources; + +import org.atriasoft.etk.Uri; +import org.atriasoft.gale.resource.Resource; +import org.atriasoft.gale.resource.ResourceVirtualArrayObject; +import org.atriasoft.loader3d.internal.Log; + +public class ResourceStaticMeshObjBynamic extends ResourceStaticMeshObj { + + public static ResourceStaticMeshObjBynamic create(final Uri uriObj) { + ResourceStaticMeshObjBynamic resource; + Resource resource2; + final String name = uriObj.getValue(); + if (name.isEmpty() || name.equals("---")) { + Log.error("Can not create a shader without a filaname"); + return null; + } + resource2 = Resource.getManager().localKeep(name); + if (resource2 != null) { + if (resource2 instanceof ResourceStaticMeshObjBynamic tmpp) { + resource2.keep(); + return tmpp; + } + Log.critical("Request resource file : '" + name + "' With the wrong type (dynamic cast error)"); + return null; + } + resource = new ResourceStaticMeshObjBynamic(uriObj); + Resource.getManager().localAdd(resource); + return resource; + } + + protected ResourceStaticMeshObjBynamic(final Uri uriFile) { + super(uriFile); + } + + /** + * Send the data to the graphic card. + */ + @Override + public void flush() { + if (this.vao == null) { + // request to the manager to be call at the next update ... + this.vao = ResourceVirtualArrayObject.createDynamic(); + this.vao.setIndices(this.indices); + this.vao.setNormals(this.normals); + this.vao.setPosition(this.vertices); + this.vao.setTextureCoordinate(this.textureCoords); + } + this.vao.flush(); + } + + public float[] getVertices() { + return this.vertices; + } + + public void setVertices(final float[] vertices) { + this.vertices = vertices; + if (this.vao != null) { + this.vao.setPosition(this.vertices); + this.vao.setVertexCount(this.vertices.length); + this.vao.flush(); + } + } +} diff --git a/src/org/atriasoft/loader3d/resources/ResourceStaticTexturedMesh.java b/src/org/atriasoft/loader3d/resources/ResourceStaticTexturedMesh.java new file mode 100644 index 0000000..eb0e39c --- /dev/null +++ b/src/org/atriasoft/loader3d/resources/ResourceStaticTexturedMesh.java @@ -0,0 +1,42 @@ +package org.atriasoft.loader3d.resources; + +import org.atriasoft.etk.Uri; +import org.atriasoft.gale.backend3d.OpenGL.RenderMode; +import org.atriasoft.gale.resource.Resource; +import org.atriasoft.gale.resource.ResourceVirtualArrayObject; + +public class ResourceStaticTexturedMesh extends ResourceStaticMesh { + public static ResourceStaticTexturedMesh create(final float[] vertices, final float[] textureCoordinates, final float[] normals, final int[] indices, final RenderMode mode) { + ResourceStaticTexturedMesh resource = new ResourceStaticTexturedMesh(vertices, textureCoordinates, normals, indices, mode); + Resource.getManager().localAdd(resource); + return resource; + } + + protected int[] indices = null; + protected float[] normals = null; + protected float[] textureCoords = null; + + protected float[] vertices = null; + + protected ResourceStaticTexturedMesh(final float[] vertices, final float[] textureCoordinates, final float[] normals, final int[] indices, final RenderMode mode) { + super(mode); + this.vertices = vertices; + this.textureCoords = textureCoordinates; + this.normals = normals; + this.indices = indices; + } + + protected ResourceStaticTexturedMesh(final Uri uriFile) { + super(uriFile); + } + + /** + * Send the data to the graphic card. + */ + public void flush() { + // request to the manager to be call at the next update ... + this.vao = ResourceVirtualArrayObject.create(this.vertices, this.textureCoords, this.normals, this.indices); + this.vao.flush(); + } + +}