1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.globaltime; 18 19 public class LatLongSphere extends Sphere { 20 21 public LatLongSphere(float centerX, float centerY, float centerZ, 22 float radius, int lats, int longs, 23 float minLongitude, float maxLongitude, 24 boolean emitTextureCoordinates, 25 boolean emitNormals, 26 boolean emitColors, 27 boolean flatten) { 28 super(emitTextureCoordinates, emitNormals, emitColors); 29 30 int tris = 2 * (lats - 1) * (longs - 1); 31 int[] vertices = new int[3 * lats * longs]; 32 int[] texcoords = new int[2 * lats * longs]; 33 int[] colors = new int[4 * lats * longs]; 34 int[] normals = new int[3 * lats * longs]; 35 short[] indices = new short[3 * tris]; 36 37 int vidx = 0; 38 int tidx = 0; 39 int nidx = 0; 40 int cidx = 0; 41 int iidx = 0; 42 43 minLongitude *= DEGREES_TO_RADIANS; 44 maxLongitude *= DEGREES_TO_RADIANS; 45 46 for (int i = 0; i < longs; i++) { 47 float fi = (float) i / (longs - 1); 48 // theta is the longitude 49 float theta = 50 (maxLongitude - minLongitude) * (1.0f - fi) + minLongitude; 51 float sinTheta = (float) Math.sin(theta); 52 float cosTheta = (float) Math.cos(theta); 53 54 for (int j = 0; j < lats; j++) { 55 float fj = (float) j / (lats - 1); 56 // phi is the latitude 57 float phi = PI * fj; 58 float sinPhi = (float) Math.sin(phi); 59 float cosPhi = (float) Math.cos(phi); 60 float x = cosTheta * sinPhi; 61 float y = cosPhi; 62 float z = sinTheta * sinPhi; 63 64 if (flatten) { 65 // Place vertices onto a flat projection 66 vertices[vidx++] = toFixed(2.0f * fi - 1.0f); 67 vertices[vidx++] = toFixed(0.5f - fj); 68 vertices[vidx++] = toFixed(0.0f); 69 } else { 70 // Place vertices onto the surface of a sphere 71 // with the given center and radius 72 vertices[vidx++] = toFixed(x * radius + centerX); 73 vertices[vidx++] = toFixed(y * radius + centerY); 74 vertices[vidx++] = toFixed(z * radius + centerZ); 75 } 76 77 if (emitTextureCoordinates) { 78 texcoords[tidx++] = toFixed(1.0f - (theta / (TWO_PI))); 79 texcoords[tidx++] = toFixed(fj); 80 } 81 82 if (emitNormals) { 83 float norm = 1.0f / Shape.length(x, y, z); 84 normals[nidx++] = toFixed(x * norm); 85 normals[nidx++] = toFixed(y * norm); 86 normals[nidx++] = toFixed(z * norm); 87 } 88 89 // 0 == black, 65536 == white 90 if (emitColors) { 91 colors[cidx++] = (i % 2) * 65536; 92 colors[cidx++] = 0; 93 colors[cidx++] = (j % 2) * 65536; 94 colors[cidx++] = 65536; 95 } 96 } 97 } 98 99 for (int i = 0; i < longs - 1; i++) { 100 for (int j = 0; j < lats - 1; j++) { 101 int base = i * lats + j; 102 103 // Ensure both triangles have the same final vertex 104 // since this vertex carries the color for flat 105 // shading 106 indices[iidx++] = (short) (base); 107 indices[iidx++] = (short) (base + 1); 108 indices[iidx++] = (short) (base + lats + 1); 109 110 indices[iidx++] = (short) (base + lats); 111 indices[iidx++] = (short) (base); 112 indices[iidx++] = (short) (base + lats + 1); 113 } 114 } 115 116 allocateBuffers(vertices, texcoords, normals, colors, indices); 117 } 118 } 119