mirror of
https://github.com/vanitasvitae/Spherical
synced 2024-11-24 21:32:07 +01:00
Fix #5
This commit is contained in:
parent
94c7d8c540
commit
89da0239f3
1 changed files with 36 additions and 56 deletions
|
@ -18,13 +18,15 @@ public class Sphere {
|
||||||
|
|
||||||
public Sphere(float radius, int polyCountX, int polyCountY) {
|
public Sphere(float radius, int polyCountX, int polyCountY) {
|
||||||
|
|
||||||
|
final int polyCountXPitch = polyCountX + 1;
|
||||||
|
|
||||||
// Setup vertex buffer.
|
// Setup vertex buffer.
|
||||||
ByteBuffer buffer = ByteBuffer.allocateDirect((polyCountX*polyCountY+2)*2*3*4);
|
ByteBuffer buffer = ByteBuffer.allocateDirect((polyCountXPitch*polyCountY+2)*3*4);
|
||||||
buffer.order(ByteOrder.nativeOrder());
|
buffer.order(ByteOrder.nativeOrder());
|
||||||
vertexBuffer = buffer.asFloatBuffer();
|
vertexBuffer = buffer.asFloatBuffer();
|
||||||
|
|
||||||
// Setup texture coordinate buffer.
|
// Setup texture coordinate buffer.
|
||||||
buffer = ByteBuffer.allocateDirect((polyCountX*polyCountY+2)*2*2*4);
|
buffer = ByteBuffer.allocateDirect((polyCountXPitch*polyCountY+2)*2*4);
|
||||||
buffer.order(ByteOrder.nativeOrder());
|
buffer.order(ByteOrder.nativeOrder());
|
||||||
textureCoordinatesBuffer = buffer.asFloatBuffer();
|
textureCoordinatesBuffer = buffer.asFloatBuffer();
|
||||||
|
|
||||||
|
@ -33,24 +35,18 @@ public class Sphere {
|
||||||
buffer.order(ByteOrder.nativeOrder());
|
buffer.order(ByteOrder.nativeOrder());
|
||||||
indexBuffer = buffer.asShortBuffer();
|
indexBuffer = buffer.asShortBuffer();
|
||||||
|
|
||||||
int polyCountXPitch = polyCountX+1; // get to same vertex on next level
|
for (int p1 = 0, level = 0; p1 < polyCountY-1; p1++) {
|
||||||
|
for (int p2 = 0; p2 < polyCountX-1; p2++) {
|
||||||
int level = 0;
|
|
||||||
|
|
||||||
for (int p1 = 0; p1 < polyCountY-1; p1++) {
|
|
||||||
//main quads, top to bottom
|
|
||||||
for (int p2 = 0; p2 < polyCountX - 1; p2++)
|
|
||||||
{
|
|
||||||
final int curr = level + p2;
|
final int curr = level + p2;
|
||||||
indexBuffer.put((short)(curr + polyCountXPitch));
|
indexBuffer.put((short)(curr + polyCountXPitch));
|
||||||
indexBuffer.put((short)(curr));
|
indexBuffer.put((short)(curr));
|
||||||
indexBuffer.put((short)(curr + 1));
|
indexBuffer.put((short)(curr + 1));
|
||||||
|
|
||||||
indexBuffer.put((short)(curr + polyCountXPitch));
|
indexBuffer.put((short)(curr + polyCountXPitch));
|
||||||
indexBuffer.put((short)(curr+1));
|
indexBuffer.put((short)(curr + 1));
|
||||||
indexBuffer.put((short)(curr + 1 + polyCountXPitch));
|
indexBuffer.put((short)(curr + 1 + polyCountXPitch));
|
||||||
}
|
}
|
||||||
|
|
||||||
// the connectors from front to end
|
|
||||||
indexBuffer.put((short)(level + polyCountX - 1 + polyCountXPitch));
|
indexBuffer.put((short)(level + polyCountX - 1 + polyCountXPitch));
|
||||||
indexBuffer.put((short)(level + polyCountX - 1));
|
indexBuffer.put((short)(level + polyCountX - 1));
|
||||||
indexBuffer.put((short)(level + polyCountX));
|
indexBuffer.put((short)(level + polyCountX));
|
||||||
|
@ -65,28 +61,20 @@ public class Sphere {
|
||||||
final int polyCountSq1 = polyCountSq + 1; // bottom point
|
final int polyCountSq1 = polyCountSq + 1; // bottom point
|
||||||
final int polyCountSqM1 = (polyCountY - 1) * polyCountXPitch; // last row's first vertex
|
final int polyCountSqM1 = (polyCountY - 1) * polyCountXPitch; // last row's first vertex
|
||||||
|
|
||||||
for (int p2 = 0; p2 < polyCountX - 1; p2++) {
|
for (int p2 = 0; p2 < polyCountX-1; p2++) {
|
||||||
// create triangles which are at the top of the sphere
|
|
||||||
|
|
||||||
indexBuffer.put((short)(polyCountSq));
|
indexBuffer.put((short)(polyCountSq));
|
||||||
indexBuffer.put((short)(p2 + 1));
|
indexBuffer.put((short)(p2 + 1));
|
||||||
indexBuffer.put((short)(p2));
|
indexBuffer.put((short)(p2));
|
||||||
|
|
||||||
// create triangles which are at the bottom of the sphere
|
|
||||||
|
|
||||||
indexBuffer.put((short)(polyCountSqM1 + p2));
|
indexBuffer.put((short)(polyCountSqM1 + p2));
|
||||||
indexBuffer.put((short)(polyCountSqM1 + p2 + 1));
|
indexBuffer.put((short)(polyCountSqM1 + p2 + 1));
|
||||||
indexBuffer.put((short)(polyCountSq1));
|
indexBuffer.put((short)(polyCountSq1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// create final triangle which is at the top of the sphere
|
|
||||||
|
|
||||||
indexBuffer.put((short)(polyCountSq));
|
indexBuffer.put((short)(polyCountSq));
|
||||||
indexBuffer.put((short)(polyCountX));
|
indexBuffer.put((short)(polyCountX));
|
||||||
indexBuffer.put((short)(polyCountX-1));
|
indexBuffer.put((short)(polyCountX-1));
|
||||||
|
|
||||||
// create final triangle which is at the bottom of the sphere
|
|
||||||
|
|
||||||
indexBuffer.put((short)(polyCountSqM1 + polyCountX - 1));
|
indexBuffer.put((short)(polyCountSqM1 + polyCountX - 1));
|
||||||
indexBuffer.put((short)(polyCountSqM1));
|
indexBuffer.put((short)(polyCountSqM1));
|
||||||
indexBuffer.put((short)(polyCountSq1));
|
indexBuffer.put((short)(polyCountSq1));
|
||||||
|
@ -94,55 +82,47 @@ public class Sphere {
|
||||||
// calculate the angle which separates all points in a circle
|
// calculate the angle which separates all points in a circle
|
||||||
final double AngleX = 2.0 * Math.PI / polyCountX;
|
final double AngleX = 2.0 * Math.PI / polyCountX;
|
||||||
final double AngleY = Math.PI / polyCountY;
|
final double AngleY = Math.PI / polyCountY;
|
||||||
|
final double InvPI = 1.0 / Math.PI;
|
||||||
|
|
||||||
int i=0;
|
|
||||||
double axz;
|
|
||||||
|
|
||||||
// we don't start at 0.
|
|
||||||
double ay = 0;//AngleY / 2;
|
double ay = 0;//AngleY / 2;
|
||||||
for (int y = 0; y < polyCountY; y++) {
|
for (int y = 0; y < polyCountY; y++) {
|
||||||
ay += AngleY;
|
|
||||||
final double sinay = Math.sin(ay);
|
|
||||||
axz = 0;
|
|
||||||
|
|
||||||
// calculate the necessary vertices without the doubled one
|
ay += AngleY;
|
||||||
for (int xz = 0; xz < polyCountX; xz++)
|
double axz = 0;
|
||||||
{
|
final double sinay = Math.sin(ay);
|
||||||
float rx = (float) (radius * Math.cos(axz) * sinay);
|
final float tv = (float) (ay*InvPI);
|
||||||
float ry = (float) (radius * Math.cos(ay));
|
|
||||||
float rz = (float) (radius * Math.sin(axz) * sinay);
|
for (int xz = 0; xz < polyCountX; xz++) {
|
||||||
|
|
||||||
|
double nx = Math.cos(axz) * sinay;
|
||||||
|
double ny = Math.cos(ay);
|
||||||
|
double nz = Math.sin(axz) * sinay;
|
||||||
|
|
||||||
// calculate texture coordinates via sphere mapping
|
// calculate texture coordinates via sphere mapping
|
||||||
// tu is the same on each level, so only calculate once
|
// tu is the same on each level, so only calculate once
|
||||||
float tu = 0.5f;
|
float tu = 0.5f;
|
||||||
if (y==0)
|
if (y == 0) {
|
||||||
{
|
if (ny != -1.0 && ny != 1.0)
|
||||||
if (ry != -1.0f && ry != 1.0f) {
|
tu = (float) (Math.acos(Math.max(Math.min(nx / sinay, 1.0), -1.0)) * 0.5 * InvPI);
|
||||||
float len = (float) Math.sqrt(rx*rx + ry*ry + rz*rz);
|
if (nz < 0.0)
|
||||||
tu = (float) (Math.acos(Math.max(Math.min(rx / len / sinay, 1.0), -1.0)) * 0.5 / Math.PI);
|
tu = 1.0f - tu;
|
||||||
}
|
} else
|
||||||
if (rz < 0.0f)
|
tu = textureCoordinatesBuffer.get(xz*2);
|
||||||
tu=1-tu;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
tu = textureCoordinatesBuffer.get((i-polyCountXPitch)*2);
|
|
||||||
|
|
||||||
vertexBuffer.put(rx);
|
vertexBuffer.put((float) (radius * nx));
|
||||||
vertexBuffer.put(ry);
|
vertexBuffer.put((float) (radius * ny));
|
||||||
vertexBuffer.put(rz);
|
vertexBuffer.put((float) (radius * nz));
|
||||||
textureCoordinatesBuffer.put(tu);
|
textureCoordinatesBuffer.put(tu);
|
||||||
textureCoordinatesBuffer.put((float)(ay/Math.PI));
|
textureCoordinatesBuffer.put(tv);
|
||||||
|
|
||||||
i++;
|
|
||||||
axz += AngleX;
|
axz += AngleX;
|
||||||
}
|
}
|
||||||
// This is the doubled vertex on the initial position
|
|
||||||
vertexBuffer.put(vertexBuffer.get((i-polyCountX)*3 + 0));
|
vertexBuffer.put(vertexBuffer.get((y*polyCountXPitch)*3 + 0));
|
||||||
vertexBuffer.put(vertexBuffer.get((i-polyCountX)*3 + 1));
|
vertexBuffer.put(vertexBuffer.get((y*polyCountXPitch)*3 + 1));
|
||||||
vertexBuffer.put(vertexBuffer.get((i-polyCountX)*3 + 2));
|
vertexBuffer.put(vertexBuffer.get((y*polyCountXPitch)*3 + 2));
|
||||||
textureCoordinatesBuffer.put(1.0f);
|
textureCoordinatesBuffer.put(1.0f);
|
||||||
textureCoordinatesBuffer.put(0.0f);
|
textureCoordinatesBuffer.put(tv);
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the vertex at the top of the sphere.
|
// Add the vertex at the top of the sphere.
|
||||||
|
|
Loading…
Reference in a new issue