# Question
Title: Android OpenGLES 2 ray picking, resulting coordinate jumpy in certain spots?
I am trying to implement object picking based on touch coordinates via an intersecting ray test. I am having trouble finding information on converting the touch coordinates to the coordinate system used in the world in order to construct this ray.

My understanding so far is that the matrix that is applied to each vertex in the scene is:

```
projectionMatrix * viewMatrix * modelMatrix

```

Here is my process for reversing that process in a an attempt to find the ray's endpoint in the scene as well as my drawing loop in case I'm simply applying the different matrices incorrectly:

```
    public float[] getMouseRayProjection(float touchX, float touchY, float windowWidth, float windowHeight, float[] modelView, float[] projection)
        {
        float[] rayDirection = new float[4];

        float normalizedX = 2 * touchX/windowWidth - 1;
        float normalizedY = 1 - 2*touchY/windowHeight;

        float[] unviewMatrix = new float[16];
        float[] viewMatrix = new float[16];
        Matrix.multiplyMM(viewMatrix, 0, projection, 0, modelView, 0);
        Matrix.invertM(unviewMatrix, 0, viewMatrix, 0);

        float[] nearPoint = multiplyMat4ByVec4(projection, new float[]{normalizedX, normalizedY, 0, 1});
        float[] modelviewInverse = new float[16];
        Matrix.invertM(modelviewInverse, 0, modelView, 0);

        float[] cameraPos = new float[4];
        cameraPos[0] = modelviewInverse[12];
        cameraPos[1] = modelviewInverse[13];
        cameraPos[2] = modelviewInverse[14];
        cameraPos[3] = modelviewInverse[15];

        rayDirection[0] = nearPoint[0] - cameraPos[0];
        rayDirection[1] = nearPoint[1] - cameraPos[1];
        rayDirection[2] = nearPoint[2] - cameraPos[2];
        rayDirection[3] = nearPoint[3] - cameraPos[3];

        return rayDirection;
        }

    public float[] multiplyMat4ByVec4(float[] matrix4, float[] vector4)
        {
        float[] returnMatrix = new float[4];

        returnMatrix[0] = (matrix4[0] * vector4[0]) + (matrix4[1] * vector4[1]) + (matrix4[2] * vector4[2]) + (matrix4[3] * vector4[3]);
        returnMatrix[1] = (matrix4[4] * vector4[0]) + (matrix4[5] * vector4[1]) + (matrix4[6] * vector4[2]) + (matrix4[7] * vector4[3]);
        returnMatrix[2] = (matrix4[8] * vector4[0]) + (matrix4[9] * vector4[1]) + (matrix4[10] * vector4[2]) + (matrix4[11] * vector4[3]);
        returnMatrix[3] = (matrix4[12] * vector4[0]) + (matrix4[13] * vector4[1]) + (matrix4[14] * vector4[2]) + (matrix4[15] * vector4[3]);

        return returnMatrix;
        }

@Override
public void onDrawFrame(GL10 gl10) {
    GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);

    long time = SystemClock.uptimeMillis() % 10000L;

    GLES20.glViewport(0, 0, (int)(width/2), (int)(height/2));
    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, 2f, 0f, 0f, 0f, 0f, 1f, 0f);
    //Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);
    drawTriangle(triangleVertices);
    drawIntersectionLine();

    //Matrix.translateM(mModelMatrix, 0, 1.5f, 0, -1f);
    //Matrix.frustumM(mProjectionMatrix, 0, left, right, -1.0f, 1.0f, 1.0f, 10.0f);
    //Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.setLookAtM(viewMatrix, 0, 1.5f, 0.8f, 0.5f, 0f, 0f, 0f, 0f, 1f, 0f);
    GLES20.glViewport((int)(width/2), (int)(height/2), (int)(width/2), (int)(height/2));
    drawTriangle(triangleVertices);
    drawIntersectionLine();

    //Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.setLookAtM(viewMatrix, 0, 0, 2f, 1f, 0, 0, 0, 0, 0, -1f);
    GLES20.glViewport((int)(width/2), 0, (int)(width/2), (int)(height/2));
    drawTriangle(triangleVertices);
    drawIntersectionLine();
}

private void drawTriangle(final FloatBuffer triangleBuffer)
{
    triangleBuffer.position(positionOffset);
    GLES20.glVertexAttribPointer(mPositionHandle, positionDataSize, GLES20.GL_FLOAT, false, strideBytes, triangleBuffer);
    GLES20.glEnableVertexAttribArray(mPositionHandle);

    triangleBuffer.position(colorOffset);
    GLES20.glVertexAttribPointer(mColorHandle, colorDataSize, GLES20.GL_FLOAT, false, strideBytes, triangleBuffer);
    GLES20.glEnableVertexAttribArray(mColorHandle);

    Matrix.multiplyMM(mMVMatrix, 0, viewMatrix, 0, mModelMatrix, 0);

    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVMatrix, 0);

    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
}

private void drawIntersectionLine()
{
    lineVertices.position(0);
    GLES20.glVertexAttribPointer(mPositionHandle, positionDataSize, GLES20.GL_FLOAT, false, lineStrideBytes, lineVertices);
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    GLES20.glDrawArrays(GLES20.GL_LINES, 0, 3);
}

private void moveIntersectionLineEndPoint(float[] lineEndPoint)
{
    this.lineEndPoint = lineEndPoint;

    float[] lineVerticesData = {
        lineStartPoint[0], lineStartPoint[1], lineStartPoint[2],
        lineEndPoint[0], lineEndPoint[1], lineEndPoint[2]
    };
    lineVertices = ByteBuffer.allocateDirect(lineVerticesData.length * bytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
    lineVertices.put(lineVerticesData).position(0);
}

```

Although I'm pretty sure my 4x4 matrix by 4d vector multiplication method is correct, here is that method as well just in case:

```
public float[] multiplyMat4ByVec4(float[] matrix4, float[] vector4)
    {
        float[] returnMatrix = new float[4];

        returnMatrix[0] = (matrix4[0] * vector4[0]) + (matrix4[1] * vector4[1]) + (matrix4[2] * vector4[2]) + (matrix4[3] * vector4[3]);
        returnMatrix[1] = (matrix4[4] * vector4[0]) + (matrix4[5] * vector4[1]) + (matrix4[6] * vector4[2]) + (matrix4[7] * vector4[3]);
        returnMatrix[2] = (matrix4[8] * vector4[0]) + (matrix4[9] * vector4[1]) + (matrix4[10] * vector4[2]) + (matrix4[11] * vector4[3]);
        returnMatrix[3] = (matrix4[12] * vector4[0]) + (matrix4[13] * vector4[1]) + (matrix4[14] * vector4[2]) + (matrix4[15] * vector4[3]);

        return returnMatrix;
    }

```

The goal of this test app is to show the scene from a few separate angles so that I can see how the intersection line looks based on my code. I wanted to draw the line starting at the camera's origin and ending at the intersection point, but it's acting oddly. The endpoint seems to be moving in accordance with the mouse for the most part, but in some spots it's seems to sort of...skip, as if there were a hole at that location or something. It's at those points that the returned numbers don't make sense and the mouse endpoint seems to shoot out in some random direction. Although I still remember a bit of linear algebra from calculus, I don't remember enough to know exactly what I'm doing here and I've scoured through many of the resources online with no luck. I'm hoping someone that reads this will have more experience dealing with this than I and will be kind enough to help me, or give me any tips if there's something else that I may be doing in an incorrect or inefficient way.

Variable Reference: Matrices are all float arrays of length 16

```
mProjectionMatrix = projection matrix

mModelMatrix = model matrix

mMVPMatrix = projection * modelview matrix

mMVMatrix = modelview matrix

    private final FloatBuffer triangleVertices;

    private FloatBuffer lineVertices;

    private final int bytesPerFloat = 4;

    private float[] viewMatrix = new float[16];

    private static Context context;

    private int mMVPMatrixHandle;

    private int mPositionHandle;

    private int mColorHandle;

    private float[] mProjectionMatrix = new float[16];

    private float[] mModelMatrix = new float[16];

    private float[] mMVPMatrix = new float[16];

    private float[] mMVMatrix = new float[16];

    private final int strideBytes = 7 * bytesPerFloat;
    private final int lineStrideBytes = 3 * bytesPerFloat;

    private final int positionOffset = 0;

    private final int positionDataSize = 3;

    private final int colorOffset = 3;

    private final int colorDataSize = 4;

    private float width, height;

    private float[] lineStartPoint = new float[]{0, 0, 1.5f};

    private float[] lineEndPoint = new float[]{0, 0, 0};

```

Just in case it helps to see the entirety of the class that handles graphics, here that is:

```
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLU;
import android.opengl.Matrix;
import android.opengl.GLSurfaceView;
import android.os.SystemClock;
import android.util.Log;

public class OpenGLRenderer implements GLSurfaceView.Renderer {

    private final FloatBuffer triangleVertices;

    private FloatBuffer lineVertices;

    private final int bytesPerFloat = 4;

    private float[] viewMatrix = new float[16];

    private static Context context;

    private int mMVPMatrixHandle;

    private int mPositionHandle;

    private int mColorHandle;

    private float[] mProjectionMatrix = new float[16];

    private float[] mModelMatrix = new float[16];

    private float[] mMVPMatrix = new float[16];

    private float[] mMVMatrix = new float[16];

    private int[] viewport = new int[4];

    private final int strideBytes = 7 * bytesPerFloat;
    private final int lineStrideBytes = 3 * bytesPerFloat;

    private final int positionOffset = 0;

    private final int positionDataSize = 3;

    private final int colorOffset = 3;

    private final int colorDataSize = 4;

    private float width, height;

    private float[] lineStartPoint = new float[]{0, 0, 1f};

    private float[] lineEndPoint = new float[]{0, 0, 0};

    public OpenGLRenderer(Context context) {
        this.context = context;

        final float[] triangleVerticesData = {
                -0.5f, -0.25f, 0.0f,
                1.0f, 0.0f, 0.0f, 1.0f,

                0.5f, -0.25f, 0.0f,
                0.0f, 0.0f, 1.0f, 1.0f,

                0.0f, 0.559016994f, 0.0f,
                0.0f, 1.0f, 0.0f, 1.0f
        };

        triangleVertices = ByteBuffer.allocateDirect(triangleVerticesData.length * bytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
        triangleVertices.put(triangleVerticesData).position(0);

        float[] lineVerticesData = {
            lineStartPoint[0], lineStartPoint[1], lineStartPoint[2],
            lineEndPoint[0], lineEndPoint[1], lineEndPoint[2]
        };
        lineVertices = ByteBuffer.allocateDirect(lineVerticesData.length * bytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
        lineVertices.put(lineVerticesData).position(0);
    }

    @Override
    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 0.5f);

        final float eyeX = 0.0f;
        final float eyeY = 0.0f;
        final float eyeZ = 2.5f;

        final float lookX = 0.0f;
        final float lookY = 0.0f;
        final float lookZ = -5.0f;

        final float upX = 0.0f;
        final float upY = 1.0f;
        final float upZ = 0.0f;

        Matrix.setLookAtM(viewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);

        try {
            int vertexShaderHandle = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);

            if (vertexShaderHandle != 0)
            {
                GLES20.glShaderSource(vertexShaderHandle, readShader("vertexShader"));

                GLES20.glCompileShader(vertexShaderHandle);

                final int[] compileStatus = new int[1];
                GLES20.glGetShaderiv(vertexShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);

                if (compileStatus[0] == 0)
                {
                    GLES20.glDeleteShader(vertexShaderHandle);
                    vertexShaderHandle = 0;
                }
            }

            if (vertexShaderHandle == 0)
            {
                throw new RuntimeException("Error creating vertex shader");
            }

            int fragmentShaderHandle = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);

            if (fragmentShaderHandle != 0)
            {
                GLES20.glShaderSource(fragmentShaderHandle, readShader("fragmentShader"));

                GLES20.glCompileShader(fragmentShaderHandle);

                final int[] compileStatus = new int[1];
                GLES20.glGetShaderiv(fragmentShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);

                if (compileStatus[0] == 0)
                {
                    GLES20.glDeleteShader(fragmentShaderHandle);
                    fragmentShaderHandle = 0;
                }
            }
            if (fragmentShaderHandle == 0)
            {
                throw new RuntimeException("Error creating fragment shader.");
            }

            int programHandle = GLES20.glCreateProgram();

            if (programHandle != 0)
            {
                GLES20.glAttachShader(programHandle, vertexShaderHandle);
                GLES20.glAttachShader(programHandle, fragmentShaderHandle);

                GLES20.glBindAttribLocation(programHandle, 0, "a_Position");
                GLES20.glBindAttribLocation(programHandle, 1, "a_Color");

                GLES20.glLinkProgram(programHandle);

                final int[] linkStatus = new int[1];
                GLES20.glGetProgramiv(programHandle, GLES20.GL_LINK_STATUS, linkStatus, 0);

                if (linkStatus[0] == 0)
                {
                    GLES20.glDeleteProgram(programHandle);
                    programHandle = 0;
                }
            }

            if (programHandle == 0)
            {
                throw new RuntimeException("Error creating program.");
            }

            mMVPMatrixHandle = GLES20.glGetUniformLocation(programHandle, "u_MVPMatrix");
            mPositionHandle = GLES20.glGetAttribLocation(programHandle, "a_Position");
            mColorHandle = GLES20.glGetAttribLocation(programHandle, "a_Color");

            GLES20.glUseProgram(programHandle);
        } catch (IOException e)
        {
            Log.d("OpenGLES2Test", "The shader could not be read: " + e.getMessage());
        } catch (RuntimeException e)
        {
            Log.d("OpenGLES2Test", e.getMessage());
        }

        GLES20.glEnable(GLES20.GL_DEPTH_TEST);
        GLES20.glDepthFunc(GLES20.GL_LEQUAL);
        GLES20.glDepthMask(true);
    }

    @Override
    public void onSurfaceChanged(GL10 gl10, int width, int height) {
        GLES20.glViewport(0, 0, width/2, height/2);

        this.width = width;
        this.height = height;

        final float ratio = (float) width / height;
        final float left = -ratio;
        final float right = ratio;
        final float bottom = -1.0f;
        final float top = 1.0f;
        final float near = 1.0f;
        final float far = 10.0f;

        GLES20.glGetIntegerv(GLES20.GL_VIEWPORT, viewport, 0);

        Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
    }

    @Override
    public void onDrawFrame(GL10 gl10) {
        GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);

        long time = SystemClock.uptimeMillis() % 10000L;

        GLES20.glViewport(0, 0, (int)(width/2), (int)(height/2));
        Matrix.setIdentityM(mModelMatrix, 0);
        Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, 2f, 0f, 0f, 0f, 0f, 1f, 0f);
        //Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);
        drawTriangle(triangleVertices);
        drawIntersectionLine();

        //Matrix.translateM(mModelMatrix, 0, 1.5f, 0, -1f);
        //Matrix.frustumM(mProjectionMatrix, 0, left, right, -1.0f, 1.0f, 1.0f, 10.0f);
        //Matrix.setIdentityM(mModelMatrix, 0);
        Matrix.setLookAtM(viewMatrix, 0, 1.5f, 0.8f, 0.5f, 0f, 0f, 0f, 0f, 1f, 0f);
        GLES20.glViewport((int)(width/2), (int)(height/2), (int)(width/2), (int)(height/2));
        drawTriangle(triangleVertices);
        drawIntersectionLine();

        //Matrix.setIdentityM(mModelMatrix, 0);
        Matrix.setLookAtM(viewMatrix, 0, 0, 2f, 1f, 0, 0, 0, 0, 0, -1f);
        GLES20.glViewport((int)(width/2), 0, (int)(width/2), (int)(height/2));
        drawTriangle(triangleVertices);
        drawIntersectionLine();
    }

    private void drawTriangle(final FloatBuffer triangleBuffer)
    {
        triangleBuffer.position(positionOffset);
        GLES20.glVertexAttribPointer(mPositionHandle, positionDataSize, GLES20.GL_FLOAT, false, strideBytes, triangleBuffer);
        GLES20.glEnableVertexAttribArray(mPositionHandle);

        triangleBuffer.position(colorOffset);
        GLES20.glVertexAttribPointer(mColorHandle, colorDataSize, GLES20.GL_FLOAT, false, strideBytes, triangleBuffer);
        GLES20.glEnableVertexAttribArray(mColorHandle);

        Matrix.multiplyMM(mMVMatrix, 0, viewMatrix, 0, mModelMatrix, 0);

        Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVMatrix, 0);

        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
    }

    private void drawIntersectionLine()
    {
        lineVertices.position(0);
        GLES20.glVertexAttribPointer(mPositionHandle, positionDataSize, GLES20.GL_FLOAT, false, lineStrideBytes, lineVertices);
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        GLES20.glDrawArrays(GLES20.GL_LINES, 0, 3);
    }

    private void moveIntersectionLineEndPoint(float[] lineEndPoint)
    {
        this.lineEndPoint = lineEndPoint;

        float[] lineVerticesData = {
            lineStartPoint[0], lineStartPoint[1], lineStartPoint[2],
            lineEndPoint[0], lineEndPoint[1], lineEndPoint[2]
        };
        lineVertices = ByteBuffer.allocateDirect(lineVerticesData.length * bytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
        lineVertices.put(lineVerticesData).position(0);
    }

    public static String readShader(String filePath) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(context.getAssets().open(filePath)));
        StringBuilder sb = new StringBuilder();
        String line;
        while( ( line = reader.readLine() ) != null)
        {
            sb.append(line + "\n");
        }
        reader.close();
        return sb.toString();
    }

    public float[] getMouseRayProjection(float touchX, float touchY, float windowWidth, float windowHeight, float[] modelView, float[] projection)
    {
        float[] rayDirection = new float[4];

        float normalizedX = 2 * touchX/windowWidth - 1;
        float normalizedY = 1 - 2*touchY/windowHeight;

        float[] unviewMatrix = new float[16];
        float[] viewMatrix = new float[16];
        Matrix.multiplyMM(viewMatrix, 0, projection, 0, modelView, 0);
        Matrix.invertM(unviewMatrix, 0, viewMatrix, 0);

        float[] nearPoint = multiplyMat4ByVec4(unviewMatrix, new float[]{normalizedX, normalizedY, 0, 1});
        float[] modelviewInverse = new float[16];
        Matrix.invertM(modelviewInverse, 0, modelView, 0);

        float[] cameraPos = new float[4];
        cameraPos[0] = modelviewInverse[12];
        cameraPos[1] = modelviewInverse[13];
        cameraPos[2] = modelviewInverse[14];
        cameraPos[3] = modelviewInverse[15];

        rayDirection[0] = (nearPoint[0] - cameraPos[0]);
        rayDirection[1] = (nearPoint[1] - cameraPos[1]);
        rayDirection[2] = (nearPoint[2] - cameraPos[2]);
        rayDirection[3] = (nearPoint[3] - cameraPos[3]);

        return rayDirection;
    }

    /*
    public float[] getOGLPosition(int x, int y)
    {
        GLU.gluUnProject(x, y, 0, , modelOffset, project, projectOffset, view, viewOffset, obj, objOffset)
    }
    */

    public float[] getCameraPos(float[] modelView)
    {
        float[] modelviewInverse = new float[16];
        Matrix.invertM(modelviewInverse, 0, modelView, 0);
        float[] cameraPos = new float[4];
        cameraPos[0] = modelviewInverse[12];
        cameraPos[1] = modelviewInverse[13];
        cameraPos[2] = modelviewInverse[14];
        cameraPos[3] = modelviewInverse[15];
        return cameraPos;
    }

    public String floatArrayAsString(float[] array)
    {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (Float f : array)
        {
            sb.append(f + ", ");
        }
        sb.deleteCharAt(sb.length() - 1);
        sb.deleteCharAt(sb.length() - 1);
        sb.append("]");
        return sb.toString();
    }

    public float[] getInverseMatrix(float[] originalMatrix)
    {
        float[] inverseMatrix = new float[16];
        Matrix.invertM(inverseMatrix, 0, originalMatrix, 0);
        return inverseMatrix;
    }

    public float[] multiplyMat4ByVec4(float[] matrix4, float[] vector4)
    {
        float[] returnMatrix = new float[4];

        returnMatrix[0] = (matrix4[0] * vector4[0]) + (matrix4[1] * vector4[1]) + (matrix4[2] * vector4[2]) + (matrix4[3] * vector4[3]);
        returnMatrix[1] = (matrix4[4] * vector4[0]) + (matrix4[5] * vector4[1]) + (matrix4[6] * vector4[2]) + (matrix4[7] * vector4[3]);
        returnMatrix[2] = (matrix4[8] * vector4[0]) + (matrix4[9] * vector4[1]) + (matrix4[10] * vector4[2]) + (matrix4[11] * vector4[3]);
        returnMatrix[3] = (matrix4[12] * vector4[0]) + (matrix4[13] * vector4[1]) + (matrix4[14] * vector4[2]) + (matrix4[15] * vector4[3]);

        return returnMatrix;
    }

    public void onTouch(float touchX, float touchY)
    {
        float[] mouseRayProjection = getMouseRayProjection(touchX, touchY, width, height, mMVMatrix, mProjectionMatrix);
        Log.d("OpenGLES2Test", "Mouse Ray: " + floatArrayAsString(mouseRayProjection));
        //Log.d("OpenGLES2Test", "ModelView: " + floatArrayAsString(mMVMatrix));
        //Log.d("OpenGLES2Test", "ModelViewInverse: " + floatArrayAsString(getInverseMatrix(mMVMatrix)));
        //Log.d("OpenGLES2Test", "Mouse Coordinates: " + touchX + ", " + touchY);
        //Log.d("OpenGLES2Test", "Ray Coordinates: " + mouseRayProjection[0] + ", " + mouseRayProjection[1] + ", " + mouseRayProjection[2] + ", " + mouseRayProjection[3]);
        moveIntersectionLineEndPoint(mouseRayProjection);
    }
}

```

# Answer
After some searching, I found a page that details this process in a different manner. Now I no longer have the issue with the end of the ray jumping to an unexpected position at random times and the end point points to the exact location it should! Here is the page I used to fix my process: http://www.antongerdelan.net/opengl/raycasting.html

And here is my final source code for the entire intersection testing app. Most of the relevant code is within the OpenGLRenderer class under the getMouseRayProjection method.

MainActivity.java:

```
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.MotionEvent;

public class MainActivity extends Activity {

    private MyGLSurfaceView mGLSurfaceView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGLSurfaceView = new MyGLSurfaceView(this);

        mGLSurfaceView.setEGLContextClientVersion(2);
        mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
        OpenGLRenderer renderer = new OpenGLRenderer(this);
        mGLSurfaceView.setRenderer(renderer);
        mGLSurfaceView.renderer = renderer;

        setContentView(mGLSurfaceView);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    protected void onResume() {
        super.onResume();
        mGLSurfaceView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mGLSurfaceView.onPause();
    }

}

class MyGLSurfaceView extends GLSurfaceView {

    public OpenGLRenderer renderer;

    public float previousX, previousY;

    public MyGLSurfaceView(Context context)
    {
        super(context);
    }

    @Override
    public boolean onTouchEvent(MotionEvent e)
    {
        float x = e.getX();
        float y = e.getY();

        switch(e.getAction()) {
        case MotionEvent.ACTION_MOVE:
            float dx = x - previousX;
            float dy = y - previousY;

            renderer.onTouch(x, y);
        }

        previousX = x;
        previousY = y;
        return true;
    }
}

```

OpenGLRenderer.java:

```
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLU;
import android.opengl.Matrix;
import android.opengl.GLSurfaceView;
import android.os.SystemClock;
import android.util.Log;

public class OpenGLRenderer implements GLSurfaceView.Renderer {

    private final FloatBuffer triangleVertices;

    private FloatBuffer lineVertices;

    private final int bytesPerFloat = 4;

    private float[] viewMatrix = new float[16];

    private static Context context;

    private int mMVPMatrixHandle;

    private int mPositionHandle;

    private int mColorHandle;

    private float[] mProjectionMatrix = new float[16];

    private float[] mModelMatrix = new float[16];

    private float[] mMVPMatrix = new float[16];

    private float[] mMVMatrix = new float[16];

    private int[] viewport = new int[4];

    private final int strideBytes = 7 * bytesPerFloat;
    private final int lineStrideBytes = 3 * bytesPerFloat;

    private final int positionOffset = 0;

    private final int positionDataSize = 3;

    private final int colorOffset = 3;

    private final int colorDataSize = 4;

    private float width, height;

    private float[] lineStartPoint = new float[]{0, 0, 1f};

    private float[] lineEndPoint = new float[]{0, 0, 0};

    private float[] cameraPos = new float[]{0f, 0f, 2.5f};
    private float[] cameraLook = new float[]{0f, 0f, -5f};
    private float[] cameraUp = new float[]{0f, 1f, 0f};

    public OpenGLRenderer(Context context) {
        this.context = context;

        final float[] triangleVerticesData = {
                -0.5f, -0.25f, 0.0f,
                1.0f, 0.0f, 0.0f, 1.0f,

                0.5f, -0.25f, 0.0f,
                0.0f, 0.0f, 1.0f, 1.0f,

                0.0f, 0.559016994f, 0.0f,
                0.0f, 1.0f, 0.0f, 1.0f
        };

        triangleVertices = ByteBuffer.allocateDirect(triangleVerticesData.length * bytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
        triangleVertices.put(triangleVerticesData).position(0);

        float[] lineVerticesData = {
            lineStartPoint[0], lineStartPoint[1], lineStartPoint[2],
            lineEndPoint[0], lineEndPoint[1], lineEndPoint[2]
        };
        lineVertices = ByteBuffer.allocateDirect(lineVerticesData.length * bytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
        lineVertices.put(lineVerticesData).position(0);
    }

    @Override
    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 0.5f);

        Matrix.setLookAtM(viewMatrix, 0, cameraPos[0], cameraPos[1], cameraPos[2], cameraLook[0], cameraLook[1], cameraLook[2], cameraUp[0], cameraUp[1], cameraUp[2]);

        try {
            int vertexShaderHandle = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);

            if (vertexShaderHandle != 0)
            {
                GLES20.glShaderSource(vertexShaderHandle, readShader("vertexShader"));

                GLES20.glCompileShader(vertexShaderHandle);

                final int[] compileStatus = new int[1];
                GLES20.glGetShaderiv(vertexShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);

                if (compileStatus[0] == 0)
                {
                    GLES20.glDeleteShader(vertexShaderHandle);
                    vertexShaderHandle = 0;
                }
            }

            if (vertexShaderHandle == 0)
            {
                throw new RuntimeException("Error creating vertex shader");
            }

            int fragmentShaderHandle = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);

            if (fragmentShaderHandle != 0)
            {
                GLES20.glShaderSource(fragmentShaderHandle, readShader("fragmentShader"));

                GLES20.glCompileShader(fragmentShaderHandle);

                final int[] compileStatus = new int[1];
                GLES20.glGetShaderiv(fragmentShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);

                if (compileStatus[0] == 0)
                {
                    GLES20.glDeleteShader(fragmentShaderHandle);
                    fragmentShaderHandle = 0;
                }
            }
            if (fragmentShaderHandle == 0)
            {
                throw new RuntimeException("Error creating fragment shader.");
            }

            int programHandle = GLES20.glCreateProgram();

            if (programHandle != 0)
            {
                GLES20.glAttachShader(programHandle, vertexShaderHandle);
                GLES20.glAttachShader(programHandle, fragmentShaderHandle);

                GLES20.glBindAttribLocation(programHandle, 0, "a_Position");
                GLES20.glBindAttribLocation(programHandle, 1, "a_Color");

                GLES20.glLinkProgram(programHandle);

                final int[] linkStatus = new int[1];
                GLES20.glGetProgramiv(programHandle, GLES20.GL_LINK_STATUS, linkStatus, 0);

                if (linkStatus[0] == 0)
                {
                    GLES20.glDeleteProgram(programHandle);
                    programHandle = 0;
                }
            }

            if (programHandle == 0)
            {
                throw new RuntimeException("Error creating program.");
            }

            mMVPMatrixHandle = GLES20.glGetUniformLocation(programHandle, "u_MVPMatrix");
            mPositionHandle = GLES20.glGetAttribLocation(programHandle, "a_Position");
            mColorHandle = GLES20.glGetAttribLocation(programHandle, "a_Color");

            GLES20.glUseProgram(programHandle);
        } catch (IOException e)
        {
            Log.d("OpenGLES2Test", "The shader could not be read: " + e.getMessage());
        } catch (RuntimeException e)
        {
            Log.d("OpenGLES2Test", e.getMessage());
        }

        GLES20.glEnable(GLES20.GL_DEPTH_TEST);
        GLES20.glDepthFunc(GLES20.GL_LEQUAL);
        GLES20.glDepthMask(true);
    }

    @Override
    public void onSurfaceChanged(GL10 gl10, int width, int height) {
        GLES20.glViewport(0, 0, width/2, height/2);

        this.width = width;
        this.height = height;

        final float ratio = (float) width / height;
        final float left = -ratio;
        final float right = ratio;
        final float bottom = -1.0f;
        final float top = 1.0f;
        final float near = 1.0f;
        final float far = 10.0f;

        GLES20.glGetIntegerv(GLES20.GL_VIEWPORT, viewport, 0);

        Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
    }

    @Override
    public void onDrawFrame(GL10 gl10) {
        GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);

        long time = SystemClock.uptimeMillis() % 10000L;

        GLES20.glViewport(0, 0, (int)(width), (int)(height));
        Matrix.setIdentityM(mModelMatrix, 0);
        Matrix.setLookAtM(viewMatrix, 0, cameraPos[0], cameraPos[1], cameraPos[2], cameraLook[0], cameraLook[1], cameraLook[2], cameraUp[0], cameraUp[1], cameraUp[2]);

        Matrix.multiplyMM(mMVMatrix, 0, viewMatrix, 0, mModelMatrix, 0);

        Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVMatrix, 0);

        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);

        drawTriangle(triangleVertices);
        drawIntersectionLine();
    }

    private void drawTriangle(final FloatBuffer triangleBuffer)
    {
        triangleBuffer.position(positionOffset);
        GLES20.glVertexAttribPointer(mPositionHandle, positionDataSize, GLES20.GL_FLOAT, false, strideBytes, triangleBuffer);
        GLES20.glEnableVertexAttribArray(mPositionHandle);

        triangleBuffer.position(colorOffset);
        GLES20.glVertexAttribPointer(mColorHandle, colorDataSize, GLES20.GL_FLOAT, false, strideBytes, triangleBuffer);
        GLES20.glEnableVertexAttribArray(mColorHandle);

        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
    }

    private void drawIntersectionLine()
    {
        lineVertices.position(0);
        GLES20.glVertexAttribPointer(mPositionHandle, positionDataSize, GLES20.GL_FLOAT, false, lineStrideBytes, lineVertices);
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        GLES20.glDrawArrays(GLES20.GL_LINES, 0, 2);
    }

    private void moveIntersectionLineEndPoint(float[] lineEndPoint)
    {
        this.lineEndPoint = lineEndPoint;

        float[] lineVerticesData = {
            lineStartPoint[0], lineStartPoint[1], lineStartPoint[2],
            lineEndPoint[0], lineEndPoint[1], lineEndPoint[2]
        };
        lineVertices = ByteBuffer.allocateDirect(lineVerticesData.length * bytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
        lineVertices.put(lineVerticesData).position(0);
    }

    public static String readShader(String filePath) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(context.getAssets().open(filePath)));
        StringBuilder sb = new StringBuilder();
        String line;
        while( ( line = reader.readLine() ) != null)
        {
            sb.append(line + "\n");
        }
        reader.close();
        return sb.toString();
    }

    public float[] getMouseRayProjection(float touchX, float touchY, float windowWidth, float windowHeight, float[] view, float[] projection)
    {
        float[] rayDirection = new float[4];

        float normalizedX = 2f * touchX/windowWidth - 1f;
        float normalizedY = 1f - 2f*touchY/windowHeight;
        float normalizedZ = 1.0f;

        float[] rayNDC = new float[]{normalizedX, normalizedY, normalizedZ};

        float[] rayClip = new float[]{rayNDC[0], rayNDC[1], -1f, 1f};

        float[] inverseProjection = new float[16];
        Matrix.invertM(inverseProjection, 0, projection, 0);
        float[] rayEye = multiplyMat4ByVec4(inverseProjection, rayClip);

        rayClip = new float[]{rayClip[0], rayClip[1], -1f, 0f};

        float[] inverseView = new float[16];
        Matrix.invertM(inverseView, 0, view, 0);
        float[] rayWorld4D = multiplyMat4ByVec4(inverseView, rayEye);
        float[] rayWorld = new float[]{rayWorld4D[0], rayWorld4D[1], rayWorld4D[2]};

        rayDirection = normalizeVector3(rayWorld);

        return rayDirection;
    }

    public float[] normalizeVector3(float[] vector3)
    {
        float[] normalizedVector = new float[3];
        float magnitude = (float) Math.sqrt((vector3[0] * vector3[0]) + (vector3[1] * vector3[1]) + (vector3[2] * vector3[2]));
        normalizedVector[0] = vector3[0] / magnitude;
        normalizedVector[1] = vector3[1] / magnitude;
        normalizedVector[2] = vector3[2] / magnitude;
        return normalizedVector;
    }

    /*
        public float[] getMouseRayProjection(float touchX, float touchY, float windowWidth, float windowHeight, float[] modelView, float[] projection)
        {
            float[] rayDirection = new float[4];

            float normalizedX = 2 * touchX/windowWidth - 1;
            float normalizedY = 1 - 2*touchY/windowHeight;

            float[] unviewMatrix = new float[16];
            float[] viewMatrix = new float[16];
            Matrix.multiplyMM(viewMatrix, 0, projection, 0, modelView, 0);
            Matrix.invertM(unviewMatrix, 0, viewMatrix, 0);

            float[] nearPoint = multiplyMat4ByVec4(unviewMatrix, new float[]{normalizedX, normalizedY, 0, 1});
            float[] modelviewInverse = new float[16];
            Matrix.invertM(modelviewInverse, 0, modelView, 0);

            float[] cameraPos = new float[4];
            cameraPos[0] = modelviewInverse[12];
            cameraPos[1] = modelviewInverse[13];
            cameraPos[2] = modelviewInverse[14];
            cameraPos[3] = modelviewInverse[15];

            rayDirection[0] = (nearPoint[0] - cameraPos[0]);
            rayDirection[1] = (nearPoint[1] - cameraPos[1]);
            rayDirection[2] = (nearPoint[2] - cameraPos[2]);
            rayDirection[3] = (nearPoint[3] - cameraPos[3]);

            return rayDirection;
        }
     */

    /*
    public float[] getOGLPosition(int x, int y)
    {
        GLU.gluUnProject(x, y, 0, , modelOffset, project, projectOffset, view, viewOffset, obj, objOffset)
    }
    */

    public float[] getCameraPos(float[] modelView)
    {
        float[] modelviewInverse = new float[16];
        Matrix.invertM(modelviewInverse, 0, modelView, 0);
        float[] cameraPos = new float[4];
        cameraPos[0] = modelviewInverse[12];
        cameraPos[1] = modelviewInverse[13];
        cameraPos[2] = modelviewInverse[14];
        cameraPos[3] = modelviewInverse[15];
        return cameraPos;
    }

    public String floatArrayAsString(float[] array)
    {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (Float f : array)
        {
            sb.append(f + ", ");
        }
        sb.deleteCharAt(sb.length() - 1);
        sb.deleteCharAt(sb.length() - 1);
        sb.append("]");
        return sb.toString();
    }

    public float[] getInverseMatrix(float[] originalMatrix)
    {
        float[] inverseMatrix = new float[16];
        Matrix.invertM(inverseMatrix, 0, originalMatrix, 0);
        return inverseMatrix;
    }

    public float[] multiplyMat4ByVec4(float[] matrix4, float[] vector4)
    {
        float[] returnMatrix = new float[4];

        returnMatrix[0] = (matrix4[0] * vector4[0]) + (matrix4[1] * vector4[1]) + (matrix4[2] * vector4[2]) + (matrix4[3] * vector4[3]);
        returnMatrix[1] = (matrix4[4] * vector4[0]) + (matrix4[5] * vector4[1]) + (matrix4[6] * vector4[2]) + (matrix4[7] * vector4[3]);
        returnMatrix[2] = (matrix4[8] * vector4[0]) + (matrix4[9] * vector4[1]) + (matrix4[10] * vector4[2]) + (matrix4[11] * vector4[3]);
        returnMatrix[3] = (matrix4[12] * vector4[0]) + (matrix4[13] * vector4[1]) + (matrix4[14] * vector4[2]) + (matrix4[15] * vector4[3]);

        return returnMatrix;
    }

    public void onTouch(float touchX, float touchY)
    {
        float[] mouseRayProjection = getMouseRayProjection(touchX, touchY, width, height, mMVMatrix, mProjectionMatrix);
        Log.d("OpenGLES2Test", "Mouse Ray: " + floatArrayAsString(mouseRayProjection));
        //Log.d("OpenGLES2Test", "ModelView: " + floatArrayAsString(mMVMatrix));
        //Log.d("OpenGLES2Test", "ModelViewInverse: " + floatArrayAsString(getInverseMatrix(mMVMatrix)));
        //Log.d("OpenGLES2Test", "Mouse Coordinates: " + touchX + ", " + touchY);
        //Log.d("OpenGLES2Test", "Ray Coordinates: " + mouseRayProjection[0] + ", " + mouseRayProjection[1] + ", " + mouseRayProjection[2] + ", " + mouseRayProjection[3]);
        moveIntersectionLineEndPoint(mouseRayProjection);
    }
}

```

fragmentShader:

```
precision mediump float;

varying vec4 v_Color;

void main()
{
    gl_FragColor = v_Color;
}

```

vertexShader:

```
uniform mat4 u_MVPMatrix;

attribute vec4 a_Position;
attribute vec4 a_Color;

varying vec4 v_Color;

void main()
{
    v_Color = a_Color;
    gl_Position = u_MVPMatrix * a_Position;
}

```
> 2 votes

---
Tags: java, android, 3d, camera, transformation
---


# Question
Title: What tech will enable a script to run after a certain amount of time elapsed following a user's action?
I'm trying to experiment in creating an MMO browser-based game using PHP, MySQL, Javascript, HTML5, and CSS.

There is this certain functionality that I want in my game that I'm having trouble with.

In detail, here's what happens:

1. The user clicks an action
2. Then a time limit will commence
3. After the time limit, then a script will run and the changes will take place.

I've heard of cron jobs but these changes are not in a set time. It depends on when a player makes a move or something.

Here are the possible ways I can think of carrying this out:

1. You save the time when the user makes a move, and when the user checks back again, there will be a script that will check if the time the user made a move and compare it with the current time. The problem with this is that, I wan't the changes to take place even when the player is offline. With this method, the changes will only happen after the player checks back again.
2. A cron job will do the above action of checking the time the user made a move and compare it with the current time. Probably every 30 minutes or every hour. The problem with this is, won't this be too much for the server? And still, it will be every 30 minutes or so. Will this be possible too if done in seconds?
3. A combination of the two. A cron job will check every hour and it will also check every time a user logged back in.

Of course these are the solutions I can think of using only cron jobs. I don't know if there is any better technology out there. I do hope that there is a better way like actually running a script after a certain amount of time elapse after an action even when offline. If there is, tell me. I'm talking server-side here ok.

Yeah, anyone can help me out with this?

# Answer
The cron-job way is definitely the easiest one and it's good enough for normal use cases.

If the changes the users makes affects the other users (for example, make a fire, which, if let unattended it would burn other player's houses in the meantime), then you can't use the first idea. Otherwise having some sort of "TODO" lists that get completed (finish the tasks) when he relogs is fine.

You ask about 'too much for the server'. You don't have to worry about. If you keep the cron jobs constant and frequent enough, you'll have a better performance. That is, doing small things over a long period is better than cramming many into fewer time. The overhead of invoking the cron job, compared to the actual work done might be negligible.

However, here are two more ways that come to my mind right now:

1. Windows Azure. There is a PHP SDK (https://github.com/windowsazure/azure-sdk-for-php). To be more specific you'd need to create an Azure Worker Role which is deployed there. Then, from PHP you'd post some tasks to be done in a Queue container. The Worker role polls for remaining tasks and executes them.
2. Node.js (http://nodejs.org/). You can create a server that, just like the Windows Azure Worker role, awaits for tasks from the PHP scripts. Then, you'd just have to move the logic of time-based work in those tasks. You can look for more info in here: http://dev.iron.io/worker/languages/nodejs/
> 1 votes

---
Tags: mmo, php, timer
---


# Question
Title: How to sync game tick in peer to peer game?
I am making a 2-player iphone action game using a synchronization service (in this case Firebase). The service allows state syncing through the internet, but I have to execute all game logic on the phones.

I've read a bunch of game networking articles, and since I have no server, it seems like *if I can get both phones to start the game at "exactly" the same time in realtime, I can adjust everything from there*. (Planning on using a "tick" count on each phone, and sending the tick along with actions, then rewinding the simulation if necessary. The phones divide the game into halves to determine authority).

**But how do you get remote clients to start a game tick at the same time??** It seems like this would be necessarily in lock step peer-to-peer, and something like it in FPS games.

The strategy I'm using now tries to have one client "guess" the other client's clock time, including ping time. If correct, they both start the game based on the guess (since for that message it was on).

* a: sends a.localTime
* b: receives message. Returns b.localTime, and dTime(a-b)
* a: receives message. Returns a.localTime, and dTime(b-a)
* b: receives message. If a.localTime + dTime(b-a) is very close to new b.localTime, send accept message.
* b: starts game at: new b.localTime + 1 second
* a: receives accept. Starts game at accepted a.localTime + dTime(b-a) + 1s

I made a little number counter thing to go with the tick, and they're just barely off. I can't see how this is possible though, since A "guessed" B's time, they should start at exactly the same time...

**See anything wrong with my method? What's an easier way?** I'm trying to avoid using a server if possible.

# Answer
I think your algorithm is pretty close to one I wrote in this answer to a similar question, but I'm concerned that this line in your algorithm isn't doing what you'd like:

> b: receives message. If a.localTime + dTime(b-a) is very close to new b.localTime, send accept message.

You should be figuring out roughly how long the packets are taking to get from `a` to `b`, and adjust `b`'s clock to equal `a.localTime - (averageRTT / 2)`. RTT stands for Round Trip Time and is easily acquired by timing how long it takes the other side to reply.

The reason that clock sync methods can only get so accurate is because the time it takes packets to get from A to B will vary from packet to packet. A lot of the variance comes from each piece of hardware between point A and B. For an example:

* Router queues can add a variable delay
* If you're using TCP and packets get dropped, there will be an additional delay
* Wireless transmission systems are particularly lossy and can introduce delays
* etc.

Since you can't be sure how long it will take each packet to arrive, the best you can do is get a reasonable estimate of the round trip time (RTT). Since the RTT is used to sync the clocks, the best anyone can do is related to how accurate the RTT is.
> 1 votes

---
Tags: iphone, networking, timer, synchronization, peer-to-peer
---


title: OpenGL VBO - load a normals index

text:
# Question
Title: OpenGL VBO - load a normals index
Okay I have the following code that works correctly. It loads a vertex array, a normal array and a vertex index array then draws them with some simple light shading.

To load the buffers:

```
//Load Buffers
//vertices
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, verts.size() * sizeof(verts), &verts[0], GL_STATIC_DRAW); //verts is std::vector<float>
//normals
glGenBuffers(1, &normalbuffer);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(normals), &normals[0], GL_STATIC_DRAW); //normals is std::vector<float>
//indices
glGenBuffers(1, &elementbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLushort), &indices[0] , GL_STATIC_DRAW);
//indices is std::vector<unsigned short> and in this working example only
//contains indices into the vertex array (I will add interleaved normal indices)

```

To draw the buffers:

```
//Draw Object
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_NORMAL_ARRAY );

//vertices
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(0);

//Indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);

//Normals
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glNormalPointer(GL_FLOAT, 0, (void*)0 );

//Draw the mesh
glDrawElements( GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, (void*)0);

//Clean up
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

```

In this code, normals are not indexed. I would like to change it so that the normals are based on the the index in `indices[]` (same as vertices are now). `indices[]` is interleaved (not in the above code) as such: {vertex index,normal index,vertex index,normal index...}.

I've been trying to get this to work for some time without success and every example I've found online seems to use a different approach to VBOs making it very difficult to combine multiple examples into one that does what I need.

Help would be greatly appreciated. And if I'm doing anything in a less than ideal way, I'm open to suggestions.

# Answer
> In this code, normals are not indexed.

They most certainly are. They merely share the same index as the position.

What you want is not generally possible. All vertex attributes *must* use the same index. You must convert your multi-indexed data to single-indices per vertex.

There are techniques you could use to avoid this, but they generally require semi-advanced hardware and will lower your overall vertex throughput performance.
> 7 votes

---
Tags: c++, opengl, vbo
---


title: Spherical map representation

text:
# Question
Title: Spherical map representation
My latest game will take place on a small planetoid. I am looking for good data structure for representing cells on the surface of a sphere. Triangles, squares, pentagons, hexagons? Which one minimises stretch the most and creates the best tiling?

Spherical mapping is the easiest but the stretch at the poles is unacceptable. Cubemapping is also fairly easy but there would still be considerable stretch near the cube corners. Subdividing an icosahedron seems the best in terms of stretch but there is the problem of indexing many triangular arrays and finding neighbouring cells at the boundaries would be difficult.

I guess I could use a single linear array of points representing N-gons, each with an array of N neighbour indices, but that seems like a huge waste of space.

The game has RTS elements so I will be storing things like influence maps and performing A\* pathfinding and convolution, so the representation has to be efficient.

# Answer
Okay, for anyone interested in this topic I will now detail the solution I have chosen. Thanks to every one who replied and gave me ideas.

First, for the 'best' tesselation, I will choose the truncated icosahedron as a starting point. Subdividing it leads to a very nice tesselation of hexagons with 12 pentagons providing the curvature. Also, continuing the subdivision on its dual will give me a very good triangular mesh for rendering with nice properties. Regarding the 12 pentagonal cells: I can ignore them, make them special (like the only places bases can be constructed), or I can hide them under scenery.

The hexagonal and pentagonal cells will be stored in a half edge data structure for easy access to neighbours and fast traversal. The only tricky part is finding which cell a given world point is in, but that can be done by starting at a random cell and walking towards the point through neighbours.

I hope someone finds this information useful. I have learned a lot and am looking forward to getting some results.

**Edit:**

Here is an image showing the result of my icosahedron subdivision and dual mesh switching using half-edge data structure.

I may do a few iterations of relaxation to get the cell areas even more uniform.
> 12 votes

# Answer
There is a way to do this rather elegantly based on subdividing an icosahedron, as you suggested in your question. An icosahedron is made of 20 equilateral triangles, and these triangles can be grouped into 5 sets, where the 4 triangles in a set form a parallelogram shape:

(The groups of four triangles with a squiggle drawn through them are the parallelograms I'm talking about. The arrows say which edges would be glued together to fold this up into an icosahedron.)

If these triangles are subdivided into smaller triangles, the whole parallelogram can be indexed like an n by 4n rectangular array (n = 4 in the example):

The numbers in each cell are the column numbers of the rectangular array. The rules for finding neighbors within the array are fairly simple: the horizontal neighbors are just plus or minus 1 column, while the vertical neighbor is either minus one row and plus one column, or plus one row and minus one column, depending on whether the column number is even or odd, respectively.

However, you still have to write some special-case code for finding neighbors that cross the boundary from one parallelogram to the next. It's a bit tricky since in some places, the top or bottom of one parallelogram will be connected to the side of another, or the top and bottom will be connected with a horizontal offset between them, etc. Possibly a half-edge structure or similar for the parallelograms would be useful here. However, at least the relationships are symmetrical amongst all 5 parallelograms: they all follow the same pattern in which side is connected to which other side of their neighbors.
> 8 votes

# Answer
Hmmm - the comments about stretch indicate you're moving between spherical and planar mapping, that's what leads to the distortions at the poles

If you want the tiles to be flat and uniform, you're correct that a icosahedron, specifically a truncated icosahedron is pretty common

You can find all of the different mappings here - Spherical Polyhedrons on wikipedia

As far as maintaining the relationships between the faces, that's a topology problem - you might find either winged edge or quad edge helpful (and you get the wonderful opportunity to meet a whole new form of algebra) Winged Edge
> 3 votes

# Answer
I guess I'm coming a little bit late to the party, but here's a possible solution that can be used to maintain a spherical world of arbitrary size and uniform appearance.

The key thing to understand here is that the world isn't flat, and therefore a 100% uniform tiling would be impossible (this follows from the so-called Hairy Ball Theorem). Some irregularities have to be allowed, and the best we could hope for is to spread those irregularities evenly around the surface, making each as small as possible.

It's actually quite easy to do in non-deterministic way. First, choose N random points uniformly around the surface. Make sure those points are actually uniform (see Sphere point picking, formulas 9-11). In second step we make those points less random and more uniform: assume all those points have negative electric charge so that they repel each other. Simulate the movement of the points for several steps, until they converge into an equilibrium state. This final configuration of the points will give you a mesh which is nearly uniformly distributed around the surface of the sphere.
> 2 votes

---
Tags: maps, sphere
---


# Question
Title: How can one implement a 3D Grid-based Line of Sight algorithm?
I'm creating a grid based Tactical RPG game in XNA.

Image below kinda explains the idea. But if you've played Dwarf Fortress before, I'm basically trying to create that 3D line of sight and you can ignore my explanation.

(Also I don't care about how efficient the algorithm is at this time.)

Currently I am drawing a Bresenham line to each square within a radius, and each square I visit I check in the direction I am headed if I run into any walls.

The code below is my check for if a position is visible. `sx, sy, sz` is the change in the grid. For instance, if the line is traveling north east, `sx = 1, sy = -1, sz = 0`. if I'm headed straight up it would be `sx=0, sy = 0, sz = 1;` etc.

```
    private bool IsVisible(APoint Cur, int sx, int sy, int sz)
    {
        bool Visible = true;
        if (ValidCoordinates(Cur))
        {
            int newsx = -1;
            int newsy = -1;
            int newsz = -1;
            switch (sx)
            {
                case -1:
                    newsx = 3; //west
                    break;
                case 0:
                    newsx = -1;
                    break;
                case 1:
                    newsx = 1; //east
                    break;
            }

            switch (sy)
            {
                case -1:
                    newsy = 0;// north
                    break;
                case 0:
                    newsy = -1;
                    break;
                case 1:
                    newsy = 2; //south
                    break;
            }

            switch (sz)
            {
                case -1:
                    newsz = 4; // down
                    break;
                case 0:
                    newsz = -1;
                    break;
                case 1:
                    newsz = 5; // up
                    break;
            }
            if (ValidCoordinates(Cur.X + sx, Cur.Y + sy, Cur.Z + sz))
            {
                if (newsx != -1 && newsy == -1 && newsz == -1) // X only.
                {
                    if (TileArray[Cur.X + sx, Cur.Y + sy, Cur.Z + sz].AllowSight(newsx))
                        Visible = true;
                    else
                        Visible = false;
                }

                if (newsx == -1 && newsy != -1 && newsz == -1) // Y only.
                {
                    if (TileArray[Cur.X + sx, Cur.Y + sy, Cur.Z + sz].AllowSight(newsy))
                        Visible = true;
                    else
                        Visible = false;
                }

                if (newsx != -1 && newsy != -1 && newsz == -1) // X and Y only
                {
                    if (Visible && TileArray[Cur.X + sx, Cur.Y + sy, Cur.Z + sz].AllowSight(newsx))
                        Visible = true;
                    else
                        Visible = false;

                    if (Visible && TileArray[Cur.X + sx, Cur.Y + sy, Cur.Z + sz].AllowSight(newsy))
                        Visible = true;
                    else
                        Visible = false;
                }

            }
            return Visible;
        }
        return false;
    }

```

The Allow sight function is here:

```
        public bool AllowSight(int i)
    {
        if (i == -1)
            return true;

        if (i >= 0 && i <= 3)
        {
            if (TileCreateCliff && HDifferenceUp > 0)
            {
                return false;
            }
        }

        if (i == 4)
        {
            if (TileVoid)
                return true;
            else
                return false;
        }
        if (i == 5)
        {
            if (TileVoid)
                return true;
            else
                return false;
        }
        return true;
    }

```

This works fine when my character is on the base level, but looking up at higher elevations, or looking down just causes everything to break.

How should I implement this?

# Answer
This is very similar to how you might do lighting with shadows in a cube/voxel game.

Essentially, you recursively walk through all the cubes within the sight range of the character. For each cube that's air you do a ray test between the center of that cube and the eyes of your character. I wrote a post about it as well.

The ray test can be an actual ray test with the geometry (likely faster, more complex) or simply step a test point out at small increments towards the target continually checking if your test point is at a solid position (slower, but very easy to implement).

I was able to perform lighting very quickly even using the simple step method for a ray test.
> 6 votes

---
Tags: xna, c#
---


# Question
Title: What underlying character stats would you put into your "character" object in an RPG engine
basically I'm making my own RPG/TBS engine named Uruk (making an rpg themed about the epic of gilgamesh) and I am thinking of a combat system similar to the Disgaea franchise or the Super Robot Wars franchise

I'm currently in the process of writing the "character" class (cant name it character since it causes confusion with the primitive data type "character") and right now i've decided to go with the regular RPG route of including the following base stats:

* strength
* Agility
* Willpower
* Endurance
* Luck

and the base stats would then dictate the following stats

* Attack (probably a combination of the strength stat and weapon stats)
* Physical Defense (determined by endurance and armor)
* Magic Resistance (maybe something to do with willpower and armor)
* Crit Rate (luck and agility)
* Max Health (endurance)
* Max Mana (willpower)
* Max Stamina (combination of strength and endurance)
* Move per turn (determined by character class or agility)

of course there would also be a leveling system with level and experience stats

the biggest problem I am facing right now is whether I should put additional underlying stats (hidden from the play) for leveling purposes (for example stats such as strength per level and max health per level) and how would i go for implementing said underlying stats with a class system, currently I am using an enum within the character object (calling them objects to avoid confusion with programming classes and character classes) to implement the class system and I have been considering on whether I should just write multiple objects extending on the character object for each character class or should I keep on using enums to represent different classes

# Answer
> 19 votes
## Which Stats?

First, with regards to what stats to implement, you need to work backwards from mechanics to derived stats to basic stats. Determine what effects and mechanics you want during play, and determine how you want those mechanics to work with one another.

The important notion when looking at relationships between mechanics is identifying the aspects you want to be **orthogonal**. This means which aspects are the atomic elements which are independent of one another.

For example, maybe you want misses and dodges in combat. If you want these to be separate derived stats, you might have derived stats Miss % and Dodge %. Then the question would be, should they be orthogonal? Should a character be able to dodge very well while also being very clumsy and missing often? If so, they should be orthogonal, and be based on atomic, independent basic stats. If you decide they should be related (a nimble person who can dodge well should also not miss very often), they should be derived (at least partially) from the same basic stat.

## Hide Stats?

The question of **blackboxing** (whether or not to hide certain aspects of the system from the player) is a question of simplicity versus control. Do you want to make the choices, UI, and overall game simpler for the player to understand, or would you rather they feel more in control of the stats of their characters?

## Multiple Classes or Single Class?

Finally, the question of individual Classes versus a table of variables for a single Class is a question of the level of difference between professions. If the game professions are the same except for stat levels, a single Class is fine. If there are fundamental differences in how the different professions function, multiple Classes might work better.

---
Tags: game-design, architecture, software-engineering, rpg, statistics
---


# Question
Title: Calculating specific coordinate along a path
Let's say I have a path comprised of a sequence of points that are connect by lines and arcs. The entire path has some specific length. Let's call that length 100.

What would be the mechanism to determine the exact x,y coordinate for any given point on that path?

meaning...

```
 Path path = new Path();
//fill in various lineTos and arcTos to the path here
....

Point p = getCoordsFromPath(path, 50.0f); //get the coords at the half way point on the path

Point getCoordsFromPath(Path inP, float position){
    Point ret;
    //do some magic and get the x,y at the point in the path
    //that is the position distance from start

    return ret;
}

```

TIA

# Answer
Unless your paths are parameterized based on lengths, then you'll have a bit of difficulty doing this. I'm going to give you a solution outline for paths containing only line segments, because distances are easy to calculate on line segments as they are with parameterizations.

The setup I'm assuming there is that you have n + 1 points P\_1, P\_2, ..., P\_{n}, P\_{n + 1} and a collection of n parameterized intervals: I\_{k}(t) = P\_{k} * (1 - t\_k) + t\_k * P\_{k + 1}.

You'll need to compute the lengths of these intervals as well. I'll call these L\_{1}, ..., L\_{n}.

First, you need to figure out which interval you are working over. To do this, we can simply take the input distance D and begin subtracting the distances until we find the parameterization for which that subtract causes our distance to become negative:

```
D = initial distance
k = 0
while (D >= 0)
  D -= L[k]
  k += 1
end

```

This value of k computed here tells me I'm on the kth parameterization. I take my value of D, add L\[k\] back onto it, and this number here is the length along that parameterization that I have traveled since the start of that parameterization. So to get the point along the curve, I use

```
D += L[k]
t_location = D / L[k]
point_to_be_found = P_{k} * (1 - t_location ) + t_location * P_{k + 1}

```

I'm sorry for being too abstract, but hopefully this helps with the case of line segments. A similar adaptation can be made for arc lengths. However, you have to be weary about using certain parameterizations for arc lengths, because the ratio t\_location above won't necessarily be linked to the actual distance along the curve. For example, if you have a circle parameterized by ( h, (1 - h^2) / (1 + h^2) ), the value of h corresponding to an arc length of one-quarter of the circle 1/2, but the length is pi/4.
> 6 votes

# Answer
```
currentSegment = 0;
position = (0,0);
distance = 0;
while(currentSegment < segments.count && distance < desiredDistance){
  if (desiredDistance > (distance + segments[currentSegment].length)){
    distance += segments[currentSegment].length;
    position += segments[currentSegment].positionChange;
    currentSegment++;
  } else {
    position += segments[currentSegment].positionChangeAtDistance(
      desiredDistance - distance);
    distance = desiredDistance;
  }
}
return position;

```

In my pseudocode, `positionChangeAtDistance` is a `lerp` along an arc or line.
> 2 votes

---
Tags: geometry, coordinates
---


title: Creating Gun objects with upgrades?

text:
# Question
Title: Creating Gun objects with upgrades?
I have a series of guns in my game. I use the `Gun` class/object like this:

(Just an example)

```
@interface Gun : NSObject
{
    NSString *name; // Six-shooter
    NSNumber *cost;

    NSNumber *clipPrice; // ie: 700
    NSNumber *clipCapacity; // 6
    NSNumber *ammoCapacity; // 6

    NSNumber *damage;   // 0-10

    NSNumber *accuracy; // 0-10
    NSNumber *fireRate; // 0-10
    NSNumber *range;    // 0-10
    // Not sure if I have all the stats, but this is fine for now
}

```

Lets say I want to have 3 upgrades per gun. My problem is I am not sure how to do this.

Examples:

* increase fire-rate
* increase range
* increase accuracy
* silencer
* double ammo capacity (ie: Drum)
* double clip capacity (ie: Taped magazine)

Thus my question is, I'd like to implement an upgrade system to guns but I am not sure how to do it.

Would there be an Upgrade object which is a child to the Gun class, or would it be seperate class altogether.

Thanks for your time.

# Answer
Not knowing much about your particular game, telling you what numbers to increase with an upgrade (or by how much) is a bit useless. You'll have to decide on that yourself, I'm afraid.

As to how to handle upgrades, The simplest way I can think of to do this is to turn every NSNumber into an array, and add a new attribute "UpgradeLevel". Then, whenever you need to get an attribute from your Gun, you go to, for instance:

`id damageValue = [damage objectAtIndex:UpgradeLevel];`

To handle things that simply add new features, you can make an array of bools that will then return `true` or `false` depending on the upgrade.
> 5 votes

# Answer
Personally I would use a StatModifier class and stick percentage (or just straight values) modifiers onto weapons, then you would multiply or add these modifiers to your weapons base stats.

You would need some functions to perform the calculations to get the "final stat value"

For example

```
public class StatModifier
{
    private int modValue    // value or percentage
    enum StatType { AmmoCapacity, Damage, FireRate, Range, Accuracy }

    StatType statToAffect;

    public StatModifer(int value, StatType stat)
    {
        modValue = value;
        statToEffect = stat;
    }

    public int getModValue()
    {
        return modValue;
    }

    public int setModValue(int mValue)
    {
        modValue = mValue;
    }

    public StatType getStat()
    {
        return statToEffect;
    }
}

```

then in gun class

```
@interface Gun : NSObject
{
    private List<StatModifier> gunStatModifiers;

    public void AddGunModifier(int value)
    {
        gunStatModifiers.Add(new StatModifier(value));
    }

    public void calculateGunStats()
    {
        for (int i = 0; i < gunStatModifiers.Count; i++)
        {
            switch (gunStatModifiers[i].getStat())
            {
                case Damage:
                    // add stat to base damage

                //etc etc
            }
        }
    }
}

```
> 1 votes

---
Tags: rpg, statistics
---


title: libgdx collision/picking

text:
# Question
Title: libgdx collision/picking
I am trying to make something with java libgdx (2D). One thing that I can't figure it out is how to check mouse intersection with (fore example) isometric textures that are not rectangle shaped images. I found something about pickingColorPicking algorithm in libgdx, but I can't find any docs about how to use it. Any ideas?

# Answer
You can use the `pixmap.getPixel(x,y)` method to find the color value at a certain pixel. To do collision checking, you could check the alpha value of that pixel. If it isn't zero, there is a collision.

Example:

```
public static int pixelAtPoint(float x, float y, Pixmap pix) {
    int pixel = pix.getPixel(x,y);
    return pixel;
}

```
> 1 votes

---
Tags: java, libgdx, picking
---


# Question
Title: As an artist, how do I go about gaining "experience", and how do employers define it?
I'm a freelance 3D artist, and recently I've been looking into getting a full-time job as a character/environment artist (character prefered) and up until now I've only been doing unpaid commissions with two small paid jobs along with my current paid commission, a cinematic for a modding company.

My issue is this: nearly every game artist job, no matter how large or small the studio is, requires at least two years experience in the field before most will even consider looking at your portfolio. Only recently have I gotten out of college, and I'd like to think that I'm extremely competent and self-motivated, but it's impossible to find any serious companies who won't consider me a risk for having such a limited amount of real-world experience. I've been doing free commissions to expand my portfolio for nearly 3 years to the date, but I'm fairly certain this doesn't qualify as "experience" in the eyes of employers.

So the question stands. How do employers define experience, and how do I go about gaining that 2 years of required paid experience, or do employers care once they see your portfolio?

Any help would be greatly appreciated.

# Answer
> 4 votes
> nearly every game artist job, no matter how large or small the studio is, requires at least two years experience in the field before most will even consider looking at your portfolio.

The first part of this is a reasonable assertion. The second part is a potentially very false assumption on your part.

What "experience" means, how it's measured, how many years of it you need for a particular position, and indeed what "required" means all vary from studio to studio. It's not always the case that the people who write the copy for the job requisition are the people who actually do the hiring, so sometimes there's a disconnect there. There can even be variation within a studio.

Best thing to do is probably to not worry about it, and apply to positions you think you are qualified for. You're unlikely to be blacklisted for applying and being under qualified, and you may find yourself being considered for an unlisted junior position (many studios don't list junior positions because they don't need to, given the flood of incoming applicants).

Experience or not, your portfolio is your biggest focal point, especially as an artist, and that is likely to matter far more at this stage of your career.

---
Tags: career
---


# Question
Title: Can I use a certain song in my credits as long as I credit the original author?
I am working on a commercial game and I'd like to use a certain song during the credit, because it would be very fitting for my particular game.

I know using music that other people made in your game can be illegal, but this is something pretty minor, and I was wondering how legal it is to use one of his songs, as long as I credit him (I understand most of you aren't lawyers but surely you can offer some examples or give a solid advice)

# Answer
> 17 votes
No. You can't distribute anything you don't have permission for. Crediting or not makes no difference.

Unless the song was distributed under a license which explicitly permits redistributing it (such as CC-By) you'll need to get permission from the copyright holder, else it will be copyright infringement and the copyright holder can sue you for it.

# Answer
> 9 votes
Let's rephrase this: would it be OK for the musician to take your game and sell it along with his song as long as he mentioned you somewhere in the "About" page? Without even asking you? **I did not think so.**

Since you are creating copyrighted works yourself now, I suggest you spend an hour browsing wiki on the subject of Copyright and then Trademarks to get a quick background in what they actually are and how they work. Bonus points for then realizing that you should search on Trade Secret to see how that fits in.

Your masters thesis on this subject should be to finally look up Licensing and what all those licensing agreements are that you never read because they're in awfully tiny text.

All of these subjects are there to protect YOU. With proper copyright, trademark if needed, and choice of license not even EA/ATVI could come and steal your stuff.

Now to answer the question:

**You must license that song for inclusion in your game,** doesn't matter whether it's commercial or not. Find out who published that song, write the publisher a nice letter to ask about using that piece of music. If you can find an address for the musician write him a personal letter asking about the song. Maybe they're both cool and love independent game devs, maybe not, but this is the only way to find out.

There is no "minor" when it comes to legal or illegal use, you get sued the same either way.

# Answer
> 2 votes
as @mr.Beast said no you cannot

If you do want to distribute a certain song that isn't distributed under a license that allows it, you need to contact the copyright holders for permission.

you'll need to expect to pay for that permission though and expect it to come with several conditions

# Answer
> 2 votes
Word to the wise. This point will be very important to the rights owners of the music; you state, "it would be very fitting for my particular game", while their question will be "would your particular game be at all fitting for our music?" It is up to the rights owners of the music to answer that question, not me, not you and not a bunch of online folks. Prepare a request to the music rights owners with this in mind, and respectfully promote your use of their song - explain your reasoning as to specifically how the music fits, do not assume it will necessarily be an honor to them.

# Answer
> 1 votes
## Can I use copyrighted material if I give credit?

Under most licenses, absolutely not. There are licenses that allow use which include **creative commons** licenses, as Mr Beast stated in his answer.

## Can I use copyrighted material?

If you obtain a license to do so. This can be done by contacting the copyright owner, or abiding by the license that currently exists for the work, such as the case of a CC license.

You can also use such material if it falls under **fair use**. In your case, it probably does not, but doing research on it might provide more insight into fair use precedent. However, if you decide to pursue this route, know that this is decided on a case-by-case basis. In court. Contacting the copyright owner is much simpler.

## Are there other options?

Yes, actually. As IMX answered, despite the downvotes on his/her answer, **cover versions** are not covered by copyright law in the same manner. You don't need owner permission, but you will need to pay royalties to the owner through a mechanical license.

Please note that, with the exclusion of fair use, all the answers involve a license in some manner. Mechanical licenses, contacting owners to license, utilizing the current license. There is no answer (beyond fair use, which is very limited and probably not useful in your situation) in which you can use a work without a license.

# Answer
> -2 votes
Getting a legal license might cost you something, but have you ever thought about making a rough cover-version of that song?

I think it's ok when you do it that way.

---
Tags: music, copyright
---


title: Finding Surface of Inner Volume mesh

text:
# Question
Title: Finding Surface of Inner Volume mesh
I am working on the generation of Hexahedral mesh generation using octree based discretization. I have a volume mesh (Hexahedral), using isomorphism I need to project the outermost surface vertices of inner mesh onto original mesh. Could anyone help me on how to extract the surface of inner mesh?

# Answer
> 1 votes
I think the term you are looking for "Surface nets".

In Surface nets, instead of doing an exact projection onto the mesh surface, an filtering-based approximation is used. For example, in this paper, they use an iterative smoothing process, that keeps all vertices in their original volume boundary.

# Answer
> 1 votes
I think you need to create a signed distance field based on the original mesh. Then you can use gradient descent to iteratively move the outer vertices along the gradient of the distance field towards the orginal mesh surface.

The gradient of a scalar field can be constructed like this:

```
float getFieldAtPosition(vec3 _Pos) {
    return ... <- return value of signed distance function
}

vec3 getGradientAtPosition(vec3 _Pos) {
    float epsilon = 0.01; // small offset
    vec3 gradient;
    gradient.x = getFieldAtPosition(_Pos+vec(epsilon,0,0)) - getFieldAtPosition(_Pos-vec(epsilon,0,0));
    gradient.y = getFieldAtPosition(_Pos+vec(0,epsilon,0)) - getFieldAtPosition(_Pos-vec(0,epsilon,0));
    gradient.z = getFieldAtPosition(_Pos+vec(0,0,epsilon)) - getFieldAtPosition(_Pos-vec(0,0,epsilon));
    return gradient;
}

```

Hope that helps.

---
Tags: c++, opengl, 3d-meshes
---


title: Flickering GUI on Android

text:
# Question
Title: Flickering GUI on Android
New version of Unity is causing rather weird problems on Galaxy S device. The GUI starts to flicker, tear and disappear altogether at random in different screens. But this only happens on the second launch. The first launch after full uninstall works perfectly.

Normal(first launch):

Screenshot of the flickering(after first launch)

There are no errors in LogCat that clarifies the problem and this does not affect functionality of the app, only the GUI goes bananas. This happens on other Galaxy S devices too, not just mine. This also happens in my other projects, one which is smaller and one which is larger. But on other devices like Galaxy S2 and Motorola Xoom, there are no issues.

What could be the issue here?

P.S I have contacted Unity support, but have not heard from them

# Answer
> 2 votes
Apparently there is a driver bug in some PowerVR GPUs due to Unity caching the compiled shaders. Calling `Handheld.ClearShaderCache()` before a level is loaded (Awake/Start of any script) will fix this issue.

More info here.

---
Tags: unity, android, gui
---


# Question
Title: How can I make "falling away" 3D terrain like Animal Crossing?
*Animal Crossing* has a unique way of scrolling the world map: When the character moves down, the the world rolls around and over at the top, like it's stuck to a cardboard tube:

This video shows how it moves.

How can I create this effect?

# Answer
Seems like it's just taking a "flat world" and mapping to cylindrical coordinates. Essentially wrapping the world on a cylinder. I did something similar with a flat world, but I wrapped it onto a sphere:

The way I did it for a sphere is similar to the way you'd do it for a cylinder. Choose a suitable radius (ρ or "rho" in cylindrical coordinates) for your world. For each vertex, take the XZ coordinates of your world (assuming Y is height), then covert to cylindrical coordinates using the XZ and radius plus Y. If you don't add the Y, you'll get a flat cylinder. Then convert back to Cartesian coordinates to draw in game.
> 6 votes

# Answer
I was experimenting a bit after playing Deathspank, which has a similar effect. Though I never delved into it enough to see if it could be tuned to work super well, one possibility is to just modify items in your vertex shader based on depth. A function mapping cos(depth) to a Y axis modification works. You can adjust it such that the world not only drops off in the distance but also if it closer than some depth, making the world feel especially round. You can do the same for X axis value to make it seem more spherical. I'm unsure if this is how such games actually do it; my experiments gave unsatisfactory results but I didn't play with the ratios much, so it may have been as simple as changing the rate of falloff to make it better.
> 6 votes

# Answer
You want to go from a planar world, to a cylindrical one.

A rotation around the x axis (in homogeneous coordinates) looks like this:

```
     | 1   0   0   0 |
Rx = | 0  ca  -sa  0 |
     | 0  sa   ca  0 |
     | 0   0    0  1 |

```

Where:

```
ca = cos(angle) and sa = sin(angle)

```

To calculate the angle, look at the image. The pi/2 cancels out and you are left with:

```
angle = offset_from_character.z - radius

```

Also, look at the image. The angle of the projected point is dependent on the horizontal distance from character, the distance from the sphere is dependent on the vertical.

```
new_position = character_position - vec3(0,radius,0) + Rx * vec3(0,radius+_old_position.y,0)

```

be sure to cull things that are over the horizon, otherwise the whole world will wrap around.

Disclaimer: I haven't tested this and I am no mathematics expert, but the answer is something like this. Someone please correct me if I am wrong.
> 6 votes

---
Tags: 3d, movement, maps
---