1

**Support / Object3D generating issue**

« **on:**July 23, 2018, 06:05:48 pm »

Hello,

I've been trying to create some code to generate a geosphere/icosphere, I got somewhere but the results aren't exactly perfect.

Issue 1: UV mapping still does not seem perfect (especially around the top and bottom, where texCoord.y is around 0.0 or 1.0) but around the middle (0.5) all seems fine

Issue 2: I seem to get black polygons on some devices (but I don't get these black polygons on an emulator..?)

The code till now (it's not really optimized yet since I ported most of the code from some C# code: http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html):

Any idea what I'm doing wrong here?

I've been trying to create some code to generate a geosphere/icosphere, I got somewhere but the results aren't exactly perfect.

Issue 1: UV mapping still does not seem perfect (especially around the top and bottom, where texCoord.y is around 0.0 or 1.0) but around the middle (0.5) all seems fine

Issue 2: I seem to get black polygons on some devices (but I don't get these black polygons on an emulator..?)

The code till now (it's not really optimized yet since I ported most of the code from some C# code: http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html):

Code: [Select]

`private class TriangleIndices {`

public int v1;

public int v2;

public int v3;

public TriangleIndices(int v1, int v2, int v3) {

this.v1 = v1;

this.v2 = v2;

this.v3 = v3;

}

}

private ArrayList<SimpleVector> vertexData;

private ArrayList<Integer> vertexDataIndices;

private int index;

private Map<Long, Integer> middlePointIndexCache;

// add vertex to mesh, fix position to be on unit sphere, return index

private int addVertex(SimpleVector p) {

// 0.5 is a scale factor here...

double length = Math.sqrt(p.x * p.x + p.y * p.y + p.z * p.z) / 0.5;

vertexData.add(new SimpleVector(p.x / length, p.y / length, p.z

/ length));

return index++;

}

// return index of point in the middle of p1 and p2

private int getMiddlePoint(int p1, int p2) {

// first check if we have it already

boolean firstIsSmaller = p1 < p2;

long smallerIndex = firstIsSmaller ? p1 : p2;

long greaterIndex = firstIsSmaller ? p2 : p1;

long key = (smallerIndex << 32) + greaterIndex;

if (middlePointIndexCache.containsKey(key)) {

int ret = this.middlePointIndexCache.get(key);

return ret;

}

// not in cache, calculate it

SimpleVector point1 = this.vertexData.get(p1);

SimpleVector point2 = this.vertexData.get(p2);

SimpleVector middle = new SimpleVector((point1.x + point2.x) / 2.0,

(point1.y + point2.y) / 2.0, (point1.z + point2.z) / 2.0);

// add vertex makes sure point is on unit sphere

int i = addVertex(middle);

// store it, return index

this.middlePointIndexCache.put(key, i);

return i;

}

public Object3D create(int recursionLevel) {

this.vertexData = new ArrayList<SimpleVector>();

this.vertexDataIndices = new ArrayList<Integer>();

this.middlePointIndexCache = new HashMap<Long, Integer>();

this.index = 0;

// create 12 vertices of a icosahedron

float t = (float) ((1.0f + Math.sqrt(5.0f)) / 2.0f);

addVertex(new SimpleVector(-1, t, 0));

addVertex(new SimpleVector(1, t, 0));

addVertex(new SimpleVector(-1, -t, 0));

addVertex(new SimpleVector(1, -t, 0));

addVertex(new SimpleVector(0, -1, t));

addVertex(new SimpleVector(0, 1, t));

addVertex(new SimpleVector(0, -1, -t));

addVertex(new SimpleVector(0, 1, -t));

addVertex(new SimpleVector(t, 0, -1));

addVertex(new SimpleVector(t, 0, 1));

addVertex(new SimpleVector(-t, 0, -1));

addVertex(new SimpleVector(-t, 0, 1));

// create 20 triangles of the icosahedron

List<TriangleIndices> faces = new ArrayList<TriangleIndices>();

// 5 faces around point 0

faces.add(new TriangleIndices(0, 11, 5));

faces.add(new TriangleIndices(0, 5, 1));

faces.add(new TriangleIndices(0, 1, 7));

faces.add(new TriangleIndices(0, 7, 10));

faces.add(new TriangleIndices(0, 10, 11));

// 5 adjacent faces

faces.add(new TriangleIndices(1, 5, 9));

faces.add(new TriangleIndices(5, 11, 4));

faces.add(new TriangleIndices(11, 10, 2));

faces.add(new TriangleIndices(10, 7, 6));

faces.add(new TriangleIndices(7, 1, 8));

// 5 faces around point 3

faces.add(new TriangleIndices(3, 9, 4));

faces.add(new TriangleIndices(3, 4, 2));

faces.add(new TriangleIndices(3, 2, 6));

faces.add(new TriangleIndices(3, 6, 8));

faces.add(new TriangleIndices(3, 8, 9));

// 5 adjacent faces

faces.add(new TriangleIndices(4, 9, 5));

faces.add(new TriangleIndices(2, 4, 11));

faces.add(new TriangleIndices(6, 2, 10));

faces.add(new TriangleIndices(8, 6, 7));

faces.add(new TriangleIndices(9, 8, 1));

// refine triangles

for (int i = 0; i < recursionLevel; i++) {

List<TriangleIndices> faces2 = new ArrayList<TriangleIndices>();

for (TriangleIndices tri : faces) {

// replace triangle by 4 triangles

int a = getMiddlePoint(tri.v1, tri.v2);

int b = getMiddlePoint(tri.v2, tri.v3);

int c = getMiddlePoint(tri.v3, tri.v1);

faces2.add(new TriangleIndices(tri.v1, a, c));

faces2.add(new TriangleIndices(tri.v2, b, a));

faces2.add(new TriangleIndices(tri.v3, c, b));

faces2.add(new TriangleIndices(a, b, c));

}

faces = faces2;

}

// done, now add triangles to mesh

for (TriangleIndices tri : faces) {

this.vertexDataIndices.add(tri.v1);

this.vertexDataIndices.add(tri.v2);

this.vertexDataIndices.add(tri.v3);

}

Object3D obj = new Object3D(vertexDataIndices.size() / 3);

for (int c = 0; c < (vertexDataIndices.size() / 3); c++) {

final SimpleVector aa = vertexData

.get(vertexDataIndices.get(c * 3));

final SimpleVector aaP = cartesianToPolar(aa, true);

final SimpleVector bb = vertexData.get(vertexDataIndices

.get(c * 3 + 1));

final SimpleVector bbP = cartesianToPolar(bb, true);

final SimpleVector cc = vertexData.get(vertexDataIndices

.get(c * 3 + 2));

final SimpleVector ccP = cartesianToPolar(cc, true);

// texture corrections...

if (Math.abs(aaP.z - bbP.z) > 0.5f) {

if(aaP.z>bbP.z){

aaP.z-=1.0f;

}else{

bbP.z-=1.0f;

}

}

if (Math.abs(aaP.z - ccP.z) > 0.5f) {

if(aaP.z>ccP.z){

aaP.z-=1.0f;

}else{

ccP.z-=1.0f;

}

}

if (Math.abs(bbP.z - ccP.z) > 0.5f) {

if(ccP.z>bbP.z){

ccP.z-=1.0f;

}else{

bbP.z-=1.0f;

}

}

obj.addTriangle(aa, aaP.z, aaP.y, bb, bbP.z, bbP.y, cc, ccP.z,

ccP.y);

}

obj.getMesh().getTriangleCount();

return obj;

}

public static SimpleVector cartesianToPolar(SimpleVector cartesian,

boolean normalize) {

if (normalize) {

return new SimpleVector(

cartesian.length(),

1.0 - (Math.acos(cartesian.y / cartesian.length()) / Math.PI),

1.0 - (Math.atan2(cartesian.x, cartesian.z) + Math.PI / 2.0)

/ (Math.PI * 2.0) );

}

return new SimpleVector(cartesian.length(), Math.acos(cartesian.z

/ cartesian.length()), Math.atan2(cartesian.y, cartesian.x));

}

Any idea what I'm doing wrong here?