/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.globaltime;
public class LatLongSphere extends Sphere {
public LatLongSphere(float centerX, float centerY, float centerZ,
float radius, int lats, int longs,
float minLongitude, float maxLongitude,
boolean emitTextureCoordinates,
boolean emitNormals,
boolean emitColors,
boolean flatten) {
super(emitTextureCoordinates, emitNormals, emitColors);
int tris = 2 * (lats - 1) * (longs - 1);
int[] vertices = new int[3 * lats * longs];
int[] texcoords = new int[2 * lats * longs];
int[] colors = new int[4 * lats * longs];
int[] normals = new int[3 * lats * longs];
short[] indices = new short[3 * tris];
int vidx = 0;
int tidx = 0;
int nidx = 0;
int cidx = 0;
int iidx = 0;
minLongitude *= DEGREES_TO_RADIANS;
maxLongitude *= DEGREES_TO_RADIANS;
for (int i = 0; i < longs; i++) {
float fi = (float) i / (longs - 1);
// theta is the longitude
float theta =
(maxLongitude - minLongitude) * (1.0f - fi) + minLongitude;
float sinTheta = (float) Math.sin(theta);
float cosTheta = (float) Math.cos(theta);
for (int j = 0; j < lats; j++) {
float fj = (float) j / (lats - 1);
// phi is the latitude
float phi = PI * fj;
float sinPhi = (float) Math.sin(phi);
float cosPhi = (float) Math.cos(phi);
float x = cosTheta * sinPhi;
float y = cosPhi;
float z = sinTheta * sinPhi;
if (flatten) {
// Place vertices onto a flat projection
vertices[vidx++] = toFixed(2.0f * fi - 1.0f);
vertices[vidx++] = toFixed(0.5f - fj);
vertices[vidx++] = toFixed(0.0f);
} else {
// Place vertices onto the surface of a sphere
// with the given center and radius
vertices[vidx++] = toFixed(x * radius + centerX);
vertices[vidx++] = toFixed(y * radius + centerY);
vertices[vidx++] = toFixed(z * radius + centerZ);
}
if (emitTextureCoordinates) {
texcoords[tidx++] = toFixed(1.0f - (theta / (TWO_PI)));
texcoords[tidx++] = toFixed(fj);
}
if (emitNormals) {
float norm = 1.0f / Shape.length(x, y, z);
normals[nidx++] = toFixed(x * norm);
normals[nidx++] = toFixed(y * norm);
normals[nidx++] = toFixed(z * norm);
}
// 0 == black, 65536 == white
if (emitColors) {
colors[cidx++] = (i % 2) * 65536;
colors[cidx++] = 0;
colors[cidx++] = (j % 2) * 65536;
colors[cidx++] = 65536;
}
}
}
for (int i = 0; i < longs - 1; i++) {
for (int j = 0; j < lats - 1; j++) {
int base = i * lats + j;
// Ensure both triangles have the same final vertex
// since this vertex carries the color for flat
// shading
indices[iidx++] = (short) (base);
indices[iidx++] = (short) (base + 1);
indices[iidx++] = (short) (base + lats + 1);
indices[iidx++] = (short) (base + lats);
indices[iidx++] = (short) (base);
indices[iidx++] = (short) (base + lats + 1);
}
}
allocateBuffers(vertices, texcoords, normals, colors, indices);
}
}
|