package com.asha.vrlib.objects; import android.content.Context; import android.graphics.RectF; import com.asha.vrlib.MD360Program; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.ShortBuffer; /** * Created by hzqiujiadi on 16/1/22. * hzqiujiadi ashqalcn@gmail.com */ public class MDDome3D extends MDAbsObject3D { float mDegree; boolean mIsUpper; RectF mTextureSize; float mPrevRatio = 1; float[] texCoordinates; public MDDome3D(RectF textureSize, float degree, boolean isUpper) { this.mTextureSize = textureSize; this.mDegree = degree; this.mIsUpper = isUpper; } @Override public void uploadTexCoordinateBufferIfNeed(MD360Program program, int index) { if (super.getTexCoordinateBuffer(index) == null){ return; } if (index == 0){ float ratio = mTextureSize.width() / mTextureSize.height(); if (ratio != mPrevRatio){ int size = texCoordinates.length; float[] tmp = new float[size]; for (int i = 0; i < size; i += 2){ tmp[i] = (texCoordinates[i]- 0.5f)/ratio + 0.5f; tmp[i+1] = texCoordinates[i+1]; } ByteBuffer cc = ByteBuffer.allocateDirect( tmp.length * 4); cc.order(ByteOrder.nativeOrder()); FloatBuffer buffer = cc.asFloatBuffer(); buffer.put(tmp); buffer.position(0); setTexCoordinateBuffer(0,buffer); setTexCoordinateBuffer(1,buffer); mPrevRatio = ratio; } } super.uploadTexCoordinateBufferIfNeed(program, index); } @Override protected void executeLoad(Context context) { generateDome(mDegree, mIsUpper, this); } private static void generateDome(float degree, boolean isUpper, MDDome3D object3D) { generateDome(18, 150, degree, isUpper, object3D); } public static void generateDome(float radius, int sectors, float degreeY, boolean isUpper, MDDome3D object3D) { final float PI = (float) Math.PI; final float PI_2 = (float) (Math.PI / 2); float percent = degreeY / 360; int rings = sectors >> 1; float R = 1f/rings; float S = 1f/sectors; short r, s; float x, y, z; int lenRings = (int) (rings * percent) + 1; int lenSectors = sectors + 1; int numPoint = lenRings * lenSectors; float[] vertexs = new float[numPoint * 3]; float[] texcoords = new float[numPoint * 2]; short[] indices = new short[numPoint * 6]; int upper = isUpper ? 1 : -1; int t = 0, v = 0; for(r = 0; r < lenRings; r++) { for(s = 0; s < lenSectors; s++) { x = (float) (Math.cos( 2 * PI * s * S ) * Math.sin( PI * r * R )) * upper; y = (float) Math.sin( -PI_2 + PI * r * R ) * -upper; z = (float) (Math.sin( 2 * PI * s * S ) * Math.sin( PI * r * R )); float a = (float) (Math.cos( 2 * PI * s * S) * r * R / percent)/2.0f + 0.5f; float b = (float) (Math.sin( 2 * PI * s * S) * r * R / percent)/2.0f + 0.5f; texcoords[t++] = b; texcoords[t++] = a; vertexs[v++] = x * radius; vertexs[v++] = y * radius; vertexs[v++] = z * radius; } } int counter = 0; for(r = 0; r < lenRings - 1; r++){ for(s = 0; s < lenSectors - 1; s++) { indices[counter++] = (short) (r * lenSectors + s); //(a) indices[counter++] = (short) ((r+1) * lenSectors + (s)); //(b) indices[counter++] = (short) ((r) * lenSectors + (s+1)); // (c) indices[counter++] = (short) ((r) * lenSectors + (s+1)); // (c) indices[counter++] = (short) ((r+1) * lenSectors + (s)); //(b) indices[counter++] = (short) ((r+1) * lenSectors + (s+1)); // (d) } } // initialize vertex byte buffer for shape coordinates ByteBuffer bb = ByteBuffer.allocateDirect( // (# of coordinate values * 4 bytes per float) vertexs.length * 4); bb.order(ByteOrder.nativeOrder()); FloatBuffer vertexBuffer = bb.asFloatBuffer(); vertexBuffer.put(vertexs); vertexBuffer.position(0); // initialize vertex byte buffer for shape coordinates ByteBuffer cc = ByteBuffer.allocateDirect( texcoords.length * 4); cc.order(ByteOrder.nativeOrder()); FloatBuffer texBuffer = cc.asFloatBuffer(); texBuffer.put(texcoords); texBuffer.position(0); // initialize byte buffer for the draw list ByteBuffer dlb = ByteBuffer.allocateDirect( // (# of coordinate values * 2 bytes per short) indices.length * 2); dlb.order(ByteOrder.nativeOrder()); ShortBuffer indexBuffer = dlb.asShortBuffer(); indexBuffer.put(indices); indexBuffer.position(0); object3D.setIndicesBuffer(indexBuffer); object3D.setTexCoordinateBuffer(0,texBuffer); object3D.setTexCoordinateBuffer(1,texBuffer); object3D.setVerticesBuffer(0,vertexBuffer); object3D.setVerticesBuffer(1,vertexBuffer); object3D.setNumIndices(indices.length); object3D.texCoordinates = texcoords; } }