Subversion Repositories AndroidProjects

Rev

Rev 53 | Rev 55 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.gebauz.pingK.game;

import java.util.Vector;

import javax.microedition.khronos.opengles.GL10;

import android.util.Log;

import com.gebauz.framework.util.GLUtil;
import com.gebauz.framework.util.Mesh;
import com.gebauz.framework.util.Texture;
import com.gebauz.framework.util.Vector2;
import com.gebauz.framework.util.renderstates.RenderStates;
import com.gebauz.pingK.R;

public class BallTrail
{
        private Ball mBall;
        private Mesh mTrailMesh = new Mesh();
        private Texture mTexture = new Texture();
        private Vector<Vector2> mTrailPoints = new Vector<Vector2>();
        private float mTrailTimer = 0.0f;
       
        public BallTrail(Ball ball)
        {
                mBall = ball;
                mTexture.loadTexture(R.drawable.icon_hourglass);
        }
       
        public void reset()
        {
                mTrailPoints.clear();
                mTrailMesh.setVertices(null);
        }
       
        private void addTrailGeometryForPoint(int i)
        {
                if (i == 0)
                {
                        // first point
                        if (mTrailPoints.size() >= 2)
                        {
                                Vector2 p0 = mTrailPoints.get(0);
                                Vector2 p1 = mTrailPoints.get(1);
                        }
                }
                else
                {
                       
                }
        }
       
        public void addTrailPoint(float x, float y)
        {
                mTrailPoints.add(new Vector2(x, y));
               
                while (mTrailPoints.size() > GameConsts.BALL_TRAIL_LENGTH)
                {
                        mTrailPoints.remove(0);
                }
               
                if (mTrailPoints.size() >= 2)
                {                      
                        // generate geometry
                       
                        // for triangle strips, we have two points per trail point
                        float[] vertices = new float[mTrailPoints.size() * Mesh.COORD_ELEMENTS_COUNT * 2];
                        float[] colors = new float[mTrailPoints.size() * Mesh.COLOR_ELEMENTS_COUNT * 2];
                       
                        // first point
                        {
                                Vector2 a = mTrailPoints.get(0);
                                Vector2 b = mTrailPoints.get(1);
                                Vector2 direction = new Vector2(b.x - a.x, b.y - a.y);
                                Vector2 normal = new Vector2(direction.y, -direction.x);
                                normal.setLength(GameConsts.BALL_TRAIL_WIDTH);
                               
                                vertices[0] = a.x + normal.x;
                                vertices[1] = a.y + normal.y;
                                vertices[2] = 0.0f;
                               
                                vertices[3] = a.x - normal.x;
                                vertices[4] = a.y - normal.y;
                                vertices[5] = 0.0f;
                               
                                colors[0] = 1.0f; colors[1] = 0.0f; colors[2] = 0.0f; colors[3] = 1.0f;
                                colors[4] = 0.0f; colors[5] = 1.0f; colors[6] = 0.0f; colors[7] = 1.0f;
                        }
                       
                        for (int i = 1; i < mTrailPoints.size(); i++)
                        {
                                Vector2 a = mTrailPoints.get(i-1);
                                Vector2 b = mTrailPoints.get(i);
                                Vector2 direction = new Vector2(b.x - a.x, b.y - a.y);
                                Vector2 normal = new Vector2(direction.y, -direction.x);
                                normal.setLength(GameConsts.BALL_TRAIL_WIDTH);
                               
                                if (i < (mTrailPoints.size()-1))
                                {
                                        // there is a next segment, so average current normal with next
                                        Vector2 nextPoint = mTrailPoints.get(i+1);
                                        Vector2 nextDirection = new Vector2(nextPoint.x - b.x, nextPoint.y - b.y);
                                        Vector2 nextNormal = new Vector2(nextDirection.y, -nextDirection.x);
                                        nextNormal.normalize();
                                        normal.normalize();
                                       
                                        normal.addVector(nextNormal);
                                        normal.setLength(GameConsts.BALL_TRAIL_WIDTH);
                                }
                                else
                                {
                                        Log.v(GameConsts.LOG_TAG, "P=" + b.x + ", " + b.y);
                                }
                               
                                vertices[i * Mesh.COORD_ELEMENTS_COUNT * 2 + 0] = b.x + normal.x;
                                vertices[i * Mesh.COORD_ELEMENTS_COUNT * 2 + 1] = b.y + normal.y;
                                vertices[i * Mesh.COORD_ELEMENTS_COUNT * 2 + 2] = 0.0f;
                                vertices[i * Mesh.COORD_ELEMENTS_COUNT * 2 + 3] = b.x - normal.x;
                                vertices[i * Mesh.COORD_ELEMENTS_COUNT * 2 + 4] = b.y - normal.y;
                                vertices[i * Mesh.COORD_ELEMENTS_COUNT * 2 + 5] = 0.0f;
                               
                                colors[i * Mesh.COLOR_ELEMENTS_COUNT * 2 + 0]   = 1.0f;
                                colors[i * Mesh.COLOR_ELEMENTS_COUNT * 2 + 1]   = 0.0f;
                                colors[i * Mesh.COLOR_ELEMENTS_COUNT * 2 + 2]   = 0.0f;
                                colors[i * Mesh.COLOR_ELEMENTS_COUNT * 2 + 3]   = 1.0f;
                                colors[i * Mesh.COLOR_ELEMENTS_COUNT * 2 + 4]   = 0.0f;
                                colors[i * Mesh.COLOR_ELEMENTS_COUNT * 2 + 5]   = 1.0f;
                                colors[i * Mesh.COLOR_ELEMENTS_COUNT * 2 + 6]   = 0.0f;
                                colors[i * Mesh.COLOR_ELEMENTS_COUNT * 2 + 7]   = 1.0f;
                        }                      
                       
                        mTrailMesh.setPrimitiveType(GL10.GL_TRIANGLE_STRIP);
                        mTrailMesh.setVertices(vertices);
                        mTrailMesh.setColors(colors);
                       
/*                      float[] vertices = new float[(mTrailPoints.size()-1) * 3 * 4];
                        float[] colors = new float[(mTrailPoints.size()-1) * 4 * 4];
                        short[] indices = new short[(mTrailPoints.size()-1) * 6];
                        float[] texCoords = new float[(mTrailPoints.size()-1) * 2 * 4];
                        int idx = 0;
                             
                        Vector2 a = mTrailPoints.get(0);
                        Vector2 b = mTrailPoints.get(1);
                       
                        for (int i = 1; i < mTrailPoints.size(); i++)
                        {
                                Vector2 lineDirectionA = new Vector2(b.x - a.x, b.y - a.y);
                                Vector2 lineNormalA = new Vector2(-lineDirectionA.y, lineDirectionA.x);

                                Vector2 lineDirectionB = new Vector2(b.x - a.x, b.y - a.y);
                                Vector2 lineNormalB = new Vector2(-lineDirectionA.y, lineDirectionA.x);
                               
                                // average if there is a next segment
                                if (i < (mTrailPoints.size() - 1))
                                {
                                        Vector2 c = mTrailPoints.get(i+1);
                                        Vector2 lineDirectionC = new Vector2(c.x - b.x, c.y - b.y);
                                        Vector2 lineNormalC = new Vector2(-lineDirectionC.y, lineDirectionC.x);
                                       
                                        lineNormalB.addVector(lineNormalC);
                                       
                                        // prepare for next loop round
                                        a = mTrailPoints.get(i);
                                        b = mTrailPoints.get(i+1);
                                }
                                lineNormalA.setLength(GameConsts.BALL_TRAIL_WIDTH);
                                lineNormalB.setLength(GameConsts.BALL_TRAIL_WIDTH);
                               
                                int i1 = (i-1)*4;
                                int i2 = (i-1)*4+1;
                                int i3 = (i-1)*4+2;
                                int i4 = (i-1)*4+3;
                               
                                vertices[i1*3+0] = a.x + lineNormalA.x;
                                vertices[i1*3+1] = a.y + lineNormalA.y;
                                vertices[i1*3+2] = 0.0f;
                               
                                vertices[i2*3+0] = b.x + lineNormalB.x;
                                vertices[i2*3+1] = b.y + lineNormalB.y;
                                vertices[i2*3+2] = 0.0f;
                               
                                vertices[i3*3+0] = b.x - lineNormalB.x;
                                vertices[i3*3+1] = b.y - lineNormalB.y;
                                vertices[i3*3+2] = 0.0f;
                               
                                vertices[i4*3+0] = a.x - lineNormalA.x;
                                vertices[i4*3+1] = a.y - lineNormalA.y;
                                vertices[i4*3+2] = 0.0f;
                               
                                colors[i1*4+0] = 1.0f; colors[i1*4+1] = 1.0f; colors[i1*4+2] = 1.0f; colors[i1*4+3] = 1.0f;
                                colors[i2*4+0] = 1.0f; colors[i2*4+1] = 1.0f; colors[i2*4+2] = 1.0f; colors[i2*4+3] = 1.0f;
                                colors[i3*4+0] = 1.0f; colors[i3*4+1] = 1.0f; colors[i3*4+2] = 1.0f; colors[i3*4+3] = 1.0f;
                                colors[i4*4+0] = 1.0f; colors[i4*4+1] = 1.0f; colors[i4*4+2] = 1.0f; colors[i4*4+3] = 1.0f;            
                               
                                indices[i1] = (short)i1;
                                indices[i2] = (short)i2;
                                indices[i3] = (short)i3;
                                indices[i4] = (short)i4;
                               
                                texCoords[idx] = 0; idx++;
                                texCoords[idx] = 1; idx++;
                                texCoords[idx] = 2; idx++;
                                texCoords[idx] = 0; idx++;
                                texCoords[idx] = 2; idx++;
                                texCoords[idx] = 3; idx++;
                        }

                        mTrailMesh.setVertices(vertices);
                        mTrailMesh.setColors(colors);
                        mTrailMesh.setIndices(indices);
                        mTrailMesh.setTexCoords(texCoords);*/

                }
        }
       
        public void update(float deltaTime)
        {
                mTrailTimer += deltaTime;
                if (mTrailTimer > GameConsts.BALL_TRAIL_INTERVAL)
                {
                        mTrailTimer -= GameConsts.BALL_TRAIL_INTERVAL;
                        addTrailPoint(mBall.getX(), mBall.getY());
                }
                //mBall
        }
       
        public void render()
        {
                GL10 gl = GLUtil.getGL();
               
                // transform
                gl.glMatrixMode(GL10.GL_MODELVIEW);
                gl.glPushMatrix();
                {
                        gl.glLoadIdentity();
                        RenderStates renderStates = GLUtil.getRenderStates();
                        renderStates.depthTest.setEnabled(false);
                        renderStates.culling.setEnabled(false);
                        renderStates.activate();
                        mTrailMesh.render(mTrailPoints.size()*2);
                        renderStates.deactivate();
                }
                gl.glPopMatrix();
        }
}