From 57c759c0f768f288d096dcd603ed80f81a40f313 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Wed, 9 Mar 2022 00:21:50 +0100 Subject: [PATCH] Correct heightmap --- .project | 11 ++ .../loader3d/resources/ResourceMesh.java | 66 +++++--- .../resources/ResourceMeshHeightMap.java | 146 +++++++++++++++--- 3 files changed, 184 insertions(+), 39 deletions(-) diff --git a/.project b/.project index 6878643..b2503f2 100644 --- a/.project +++ b/.project @@ -14,4 +14,15 @@ org.eclipse.jdt.core.javanature + + + 1646149232199 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + diff --git a/src/org/atriasoft/loader3d/resources/ResourceMesh.java b/src/org/atriasoft/loader3d/resources/ResourceMesh.java index 27f0247..919fc43 100644 --- a/src/org/atriasoft/loader3d/resources/ResourceMesh.java +++ b/src/org/atriasoft/loader3d/resources/ResourceMesh.java @@ -592,23 +592,12 @@ public class ResourceMesh extends ResourceStaticMesh { } } - // public void createViewBox( String _materialName,float _size=1.0){ - // this.normalMode = NormalMode.NONE; - // ege::viewBox::create(this.materials, this.listFaces, this.listVertex, this.listUV, - // _materialName, _size); - // calculateNormaleFace(_materialName); - // } - // - // public void createIcoSphere( String _materialName,float _size=1.0, int _subdivision=3) { - // this.normalMode = NormalMode.NONE; - // ege::icoSphere::create(this.materials, this.listFaces, this.listVertex, this.listUV, - // _materialName, _size, _subdivision); - // calculateNormaleFace(_materialName); - // } - //private boolean loadOBJ( Uri _fileName); - //private boolean loadEMF( Uri _fileName); - private void calculateNormaleFace(final String _materialName) { + protected void calculateNormaleFace(final String materialName) { this.listFacesNormal.clear(); + calculateNormaleFaceLocal(materialName); + } + + protected void calculateNormaleFaceLocal(final String _materialName) { if (this.normalMode == NormalMode.FACE) { Log.verbose("calculateNormaleFace(" + _materialName + ")"); RenderMode tmpRenderMode = this.materials.get(_materialName).getRenderMode(); @@ -617,7 +606,13 @@ public class ResourceMesh extends ResourceStaticMesh { this.normalMode = NormalMode.NONE; return; } - for (Face it : this.listFaces.get(_materialName).face()) { + FaceIndexing faceList = null; + if (this.listFaces.containsKey(_materialName)) { + faceList = this.listFaces.get(_materialName); + } else if (this.listPaletteFaces.containsKey(_materialName)) { + faceList = this.listPaletteFaces.get(_materialName); + } + for (Face it : faceList.face()) { // for all case, We use only the 3 vertex for quad element, in theory 3D modeler export element in triangle if it is not a real plane. Vector3f normal = (this.listVertex.get(it.vertex[0]).less(this.listVertex.get(it.vertex[1]))).cross(this.listVertex.get(it.vertex[1]).less(this.listVertex.get(it.vertex[2]))); //Log.info("normal: " + normal.normalized()); @@ -635,6 +630,30 @@ public class ResourceMesh extends ResourceStaticMesh { } } + // public void createViewBox( String _materialName,float _size=1.0){ + // this.normalMode = NormalMode.NONE; + // ege::viewBox::create(this.materials, this.listFaces, this.listVertex, this.listUV, + // _materialName, _size); + // calculateNormaleFace(_materialName); + // } + // + // public void createIcoSphere( String _materialName,float _size=1.0, int _subdivision=3) { + // this.normalMode = NormalMode.NONE; + // ege::icoSphere::create(this.materials, this.listFaces, this.listVertex, this.listUV, + // _materialName, _size, _subdivision); + // calculateNormaleFace(_materialName); + // } + //private boolean loadOBJ( Uri _fileName); + //private boolean loadEMF( Uri _fileName); + + protected void calculateNormaleFaces(final List materialsNames) { + this.listFacesNormal.clear(); + for (String name : materialsNames) { + Log.warning("generate normal for: '" + name + "'"); + calculateNormaleFaceLocal(name); + } + } + void clean() { //this.physics.clear(); this.materials.clear(); @@ -648,6 +667,17 @@ public class ResourceMesh extends ResourceStaticMesh { this.vao = ResourceVirtualArrayObject.createDynamic(); } + void cleanPartial() { + this.listFaces.clear(); + this.listPaletteFaces.clear(); + this.listColor.clear(); + this.listVertexNormal.clear(); + this.listFacesNormal.clear(); + this.listUV.clear(); + this.listVertex.clear(); + this.vao = ResourceVirtualArrayObject.createDynamic(); + } + protected int findColorInList(final Color _color) { for (int iii = 0; iii < this.listColor.size(); ++iii) { if (this.listColor.get(iii) == _color) { @@ -762,7 +792,7 @@ public class ResourceMesh extends ResourceStaticMesh { // calculate the normal of all faces if needed if (this.normalMode != NormalMode.NONE && this.listFacesNormal.size() == 0) { // when no normal detected == > auto generate Face normal .... - Log.error("No normal detected ???"); + Log.error("No normal detected ??? ==> abort generation of the VBO"); // calculateNormaleFace(this.listFaces.getKeys()[0]); } diff --git a/src/org/atriasoft/loader3d/resources/ResourceMeshHeightMap.java b/src/org/atriasoft/loader3d/resources/ResourceMeshHeightMap.java index a04131a..871ed7d 100644 --- a/src/org/atriasoft/loader3d/resources/ResourceMeshHeightMap.java +++ b/src/org/atriasoft/loader3d/resources/ResourceMeshHeightMap.java @@ -1,8 +1,11 @@ package org.atriasoft.loader3d.resources; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import org.atriasoft.etk.math.Vector3f; +import org.atriasoft.gale.backend3d.OpenGL.RenderMode; import org.atriasoft.loader3d.Face; import org.atriasoft.loader3d.FaceIndexing; import org.atriasoft.loader3d.NormalMode; @@ -23,6 +26,7 @@ public class ResourceMeshHeightMap extends ResourceMesh { */ public ResourceMeshHeightMap() { this.normalMode = NormalMode.FACE; + this.vao.setName("[VBO] of heightmap"); } void addPalette(String key, Material mat) { @@ -33,31 +37,131 @@ public class ResourceMeshHeightMap extends ResourceMesh { return this.palettes; } - public void udateData(float[][] heightMap, String[][] colorMap, int width, int length) throws Exception { - float ratio = 0.2f; - for (int yyy = 0; yyy < length - 1; yyy++) { - for (int xxx = 0; xxx < width - 1; xxx++) { - Vector3f vertex1 = new Vector3f(ratio * xxx, ratio * yyy, ratio * heightMap[yyy][xxx]); - this.listVertex.add(vertex1); - Vector3f vertex2 = new Vector3f(ratio * (xxx + 1), ratio * yyy, ratio * heightMap[yyy][xxx + 1]); - this.listVertex.add(vertex2); - Vector3f vertex3 = new Vector3f(ratio * xxx, ratio * (yyy + 1), ratio * heightMap[yyy + 1][xxx]); - this.listVertex.add(vertex3); - FaceIndexing currentFaceIndexing = null; - String meshFaceMaterialID = colorMap[yyy][xxx * 2]; - if (this.listPaletteFaces.containsKey(meshFaceMaterialID) == false) { - currentFaceIndexing = new FaceIndexing(); - this.listPaletteFaces.put(meshFaceMaterialID, currentFaceIndexing); + public void udateData(float[][] heightMap, String[][] colorMap, int sizeX, int sizeY) throws Exception { + float ratio = 1; + setMode(RenderMode.TRIANGLE); + //cleanPartial(); + List materialsNames = new ArrayList<>(); + for (int yyy = 0; yyy < sizeY - 1; yyy++) { + for (int xxx = 0; xxx < sizeX - 1; xxx++) { + if (xxx % 2 == 0) { + float offsetA = 0.5f; + { + int pos = this.listVertex.size(); + Vector3f vertex1 = new Vector3f(ratio * xxx, ratio * yyy, ratio * heightMap[yyy][xxx]); + this.listVertex.add(vertex1); + Vector3f vertex2 = new Vector3f(ratio * (xxx + 1), ratio * (yyy + offsetA), ratio * heightMap[yyy][xxx + 1]); + this.listVertex.add(vertex2); + Vector3f vertex3 = new Vector3f(ratio * xxx, ratio * (yyy + 1.0f), ratio * heightMap[yyy + 1][xxx]); + this.listVertex.add(vertex3); + FaceIndexing currentFaceIndexing = null; + String meshFaceMaterialID = colorMap[yyy][xxx * 2]; + if (!materialsNames.contains(meshFaceMaterialID)) { + materialsNames.add(meshFaceMaterialID); + } + if (!this.listPaletteFaces.containsKey(meshFaceMaterialID)) { + currentFaceIndexing = new FaceIndexing(); + this.listPaletteFaces.put(meshFaceMaterialID, currentFaceIndexing); + } else { + currentFaceIndexing = this.listPaletteFaces.get(meshFaceMaterialID); + } + Face face = new Face(); + face.setVertex(pos, pos + 1, pos + 2); + + currentFaceIndexing.face().add(face); + } + { + int pos = this.listVertex.size(); + Vector3f vertex1 = new Vector3f(ratio * (xxx + 1), ratio * (yyy + 1 + offsetA), ratio * heightMap[yyy + 1][xxx + 1]); + this.listVertex.add(vertex1); + Vector3f vertex2 = new Vector3f(ratio * (xxx + 1), ratio * (yyy + offsetA), ratio * heightMap[yyy][xxx + 1]); + this.listVertex.add(vertex2); + Vector3f vertex3 = new Vector3f(ratio * xxx, ratio * (yyy + 1), ratio * heightMap[yyy + 1][xxx]); + this.listVertex.add(vertex3); + FaceIndexing currentFaceIndexing = null; + String meshFaceMaterialID = colorMap[yyy][xxx * 2 + 1]; + if (!materialsNames.contains(meshFaceMaterialID)) { + materialsNames.add(meshFaceMaterialID); + } + if (!this.listPaletteFaces.containsKey(meshFaceMaterialID)) { + currentFaceIndexing = new FaceIndexing(); + this.listPaletteFaces.put(meshFaceMaterialID, currentFaceIndexing); + } else { + currentFaceIndexing = this.listPaletteFaces.get(meshFaceMaterialID); + } + Face face = new Face(); + face.setVertex(pos, pos + 1, pos + 2); + + currentFaceIndexing.face().add(face); + } } else { - currentFaceIndexing = this.listPaletteFaces.get(meshFaceMaterialID); + float offsetA = 0.5f; + { + int pos = this.listVertex.size(); + Vector3f vertex1 = new Vector3f(ratio * xxx, ratio * (yyy + offsetA), ratio * heightMap[yyy][xxx]); + this.listVertex.add(vertex1); + Vector3f vertex2 = new Vector3f(ratio * (xxx + 1), ratio * yyy, ratio * heightMap[yyy][xxx + 1]); + this.listVertex.add(vertex2); + Vector3f vertex3 = new Vector3f(ratio * (xxx + 1), ratio * (yyy + 1.0f), ratio * heightMap[yyy + 1][xxx + 1]); + this.listVertex.add(vertex3); + FaceIndexing currentFaceIndexing = null; + String meshFaceMaterialID = colorMap[yyy][xxx * 2]; + if (!materialsNames.contains(meshFaceMaterialID)) { + materialsNames.add(meshFaceMaterialID); + } + if (!this.listPaletteFaces.containsKey(meshFaceMaterialID)) { + currentFaceIndexing = new FaceIndexing(); + this.listPaletteFaces.put(meshFaceMaterialID, currentFaceIndexing); + } else { + currentFaceIndexing = this.listPaletteFaces.get(meshFaceMaterialID); + } + Face face = new Face(); + face.setVertex(pos, pos + 1, pos + 2); + + currentFaceIndexing.face().add(face); + } + { + int pos = this.listVertex.size(); + Vector3f vertex1 = new Vector3f(ratio * (xxx + 1), ratio * (yyy + 1), ratio * heightMap[yyy + 1][xxx + 1]); + this.listVertex.add(vertex1); + Vector3f vertex2 = new Vector3f(ratio * (xxx), ratio * (yyy + 1 + offsetA), ratio * heightMap[yyy + 1][xxx + 1]); + this.listVertex.add(vertex2); + Vector3f vertex3 = new Vector3f(ratio * xxx, ratio * (yyy + offsetA), ratio * heightMap[yyy][xxx]); + this.listVertex.add(vertex3); + FaceIndexing currentFaceIndexing = null; + String meshFaceMaterialID = colorMap[yyy][xxx * 2 + 1]; + if (!materialsNames.contains(meshFaceMaterialID)) { + materialsNames.add(meshFaceMaterialID); + } + if (!this.listPaletteFaces.containsKey(meshFaceMaterialID)) { + currentFaceIndexing = new FaceIndexing(); + this.listPaletteFaces.put(meshFaceMaterialID, currentFaceIndexing); + } else { + currentFaceIndexing = this.listPaletteFaces.get(meshFaceMaterialID); + } + Face face = new Face(); + face.setVertex(pos, pos + 1, pos + 2); + + currentFaceIndexing.face().add(face); + } } - Face face = new Face(); - int pos = this.listVertex.size() - 3; - face.setVertex(pos, pos + 1, pos + 2); - - currentFaceIndexing.face().add(face); } } + //Log.warning("this.listVertex: " + this.listVertex.size()); + //Log.warning("this.listFacesNormal: " + this.listFacesNormal.size()); + calculateNormaleFaces(materialsNames); + //Log.warning("this.listVertex: " + this.listVertex.size()); + //Log.warning("this.listFacesNormal: " + this.listFacesNormal.size()); + // Log.verbose("New heightmap mesh : "); + // Log.verbose(" nb vertex: " + this.listVertex.size()); + // Log.verbose(" nb UV: " + this.listUV.size()); + // Log.verbose(" nb Colors: " + this.listColor.size()); + // Log.verbose(" nb Normal face: " + this.listFacesNormal.size()); + // Log.verbose(" nb Normal vertex: " + this.listVertexNormal.size()); + // Log.verbose(" nb Faces: " + this.listFaces.size()); + // Log.verbose(" nb Faces (palette): " + this.listPaletteFaces.get(0).face().size()); + // Log.verbose(" nb material: " + this.materials.size()); + // Log.verbose(" nb palettes: " + this.palettes.size()); generateVBO(); }