Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - Edak

#1
Support / Re: 2D interface - Object Picking
August 14, 2011, 12:15:01 PM
Hey RhoX, are you still having issues finding the touched part?

Basically it goes like this,

if(TouchX > ButtonX && TouchX < ButtonX+ButtonWidth && TouchY > ButtonY && TouchY < ButtonY+ButtonHeight){
                return true;
}

Where TouchX and TouchY are the points on the screen touched.
Where ButtonX and ButtonY are the button's positions on the screen.
Where ButtonWidth and ButtonHeight are the Width and Height of the button on the screen.

I'm assuming that was your most recent question, let me know if this helps.
#2
Support / VOIP Ingame, work in progress
August 08, 2011, 09:04:02 AM
Hey all! This is a working start with server and client side, currently when connected it only records off the mic, sends through network, and plays it back on the speaker.

I've been having THE hardest time with this, not sure if anyone here could help but regardless I wanted to post the concept with hopes someone with a brighter mind that mine could solve this. I've included the server in a rar file because it uses two seperate java classes and I didn't want to post them in code tags

Known issues and points I'm struggling with:
AEC (Acoustic Noise Cancellation) I've read and read about NLMS filter, but I'm mind blown.

My phone (And from what I've read others too) has issues with plugging in head phones. the onboard mic will mute regardless of code calls to unmute it

Usage:
Set listen address and port in the voip class. Also, you must be running the server on the same network with the port open.

VOIP voice = null;
voice = new VOIP();
voice.turnOn(); //Begins listening and playing


VOIP Class (Android/Client Side)


import com.threed.jpct.Logger;

import java.net.*;
import java.io.*;
import android.media.AudioFormat;
import android.media.MediaRecorder;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.AudioManager;

class VOIP{

    Thread listenThread = null;
    Thread playThread = null;
    Socket socket = null;
    boolean Running = false;
    private int frequency = 8000;
    private int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
   
    private BufferedInputStream bis = null;
    private DataInputStream dis = null;
   
    public boolean shouldCancel;
   
    private byte[] playBuffer;

    public VOIP(MainActivity ma) {
    }

    public void connect() { //When called, connects a socket to VoiceServer
        try {
            Logger.log("Attempting connection to VoiceServer...");
            socket = new Socket("192.168.43.156", 5741);
           
            bis = new BufferedInputStream(socket.getInputStream());
            dis = new DataInputStream(bis);
        } catch (Exception ex) {
            Logger.log(ex.getMessage());
        }
    }

    public void turnOn() { //starts the listening and the playing (anything said is sent and anything recieved is played)
        if (!Running) {
            connect();
            try {
                Running = true;
                listenThread = new Thread(new Runnable() {

                    public void run() {
                        listen();
                    }
                });
                listenThread.start();


                playThread = new Thread(new Runnable() {

                    public void run() {
                        play();
                    }
                });
                playThread.start();

            } catch (Exception ex) {
                Running = false;
                Logger.log(ex.getMessage());
            }



        }
    }

    public void turnOff() {
        if (Running) {
            try {
                // Close the streams and the socket.
                socket.close();
                //Set running to false (stops the listen and play loops)
                Running = false;
            } catch (IOException ex) {
                Running = false;
                Logger.log(ex.getMessage());
            }
            //Basically terminates the threads
            //listenThread = null;
            //playThread = null;
        }
    }

    public void listen() {
        android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO);
        try {
            BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
            DataOutputStream dos = new DataOutputStream(bos);

            int bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding);
            AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                    frequency, channelConfiguration,
                    audioEncoding, bufferSize);

            byte[] micBuffer = new byte[bufferSize];
            audioRecord.startRecording();
            while (Running) {
                int bufferReadResult = audioRecord.read(micBuffer, 0, bufferSize);
                dos.write(micBuffer, 0, bufferReadResult);
            }


            audioRecord.stop();
            dos.close();

        } catch (Throwable t) {
            Logger.log("AudioRecord Recording Failed: "+t.getMessage());
        }
    }

    public void play() {
        int musicLength = AudioTrack.getMinBufferSize(frequency, channelConfiguration, audioEncoding);
        playBuffer = new byte[musicLength];
        try {

            AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                    frequency,
                    channelConfiguration,
                    audioEncoding,
                    musicLength,
                    AudioTrack.MODE_STREAM);
           
           
            audioTrack.play();

           
            while(Running){
                for(int i=0;i<musicLength;i++){
                        playBuffer[i] = (byte)dis.read();
                }
                audioTrack.write(playBuffer, 0, musicLength);
            }

// Close the input streams.
            dis.close();
           
        } catch (Throwable t) {
            Logger.log("AudioTrack Playback Failed: "+t.getMessage());
        }
    }
}



[attachment deleted by admin]
#3
Support / Re: Code example to build your own GUI menu
August 08, 2011, 08:45:20 AM
Thanks rhine, But doing so wouldn't magically make jPCT's blit include a transparency variable. I'm assuming if I supply a PNG with some transparency it would be transparent but I haven't tested it. I just don't know how to supply an alpha to blit.

Oh and you're welcome RhoX, I'm glad this is helping :-)
#4
Glad I could be of help :-)

Quick question to anyone looking:

In my Menu class  I have


public void Blit(FrameBuffer fb){
            if(show){
                fb.blit(image, srcX, srcY, destX, destY, width, height, true);
            }
        }


and would like to include a transparency, with the current way I blit textures, how do I alter transparency?
#5
You say my method is wrong, but why does it work on my phone? I  don't have my code in front of me but could it be variations in phones?
#6
Hey if what you have works so far why change it eh?
#7
Here's a method out of my 'directional pad' class, you'll have to edit the centerX and Y accordingly, but given an X and a Y (and the correct center) this will compute a radian to rotate a model by.


public float computeRadian(float x, float y) {
       
        float touchPointX = x - centerX;
        float touchPointY = centerY - y;

        double a = Math.sqrt(Math.pow(touchPointX, 2) + Math.pow(touchPointY, 2));
        double b = a;
        double c = Math.sqrt(Math.pow(touchPointX, 2) + Math.pow(touchPointY - a, 2));

        Double torsoRotate = new Double(Math.acos((Math.pow(a, 2) + Math.pow(b, 2) - Math.pow(c, 2)) / (2 * a * b)));
        //Logger.log("a: "+a+" c: "+c+" Degree: "+Degree);
        //Degree *= 0.0174532925; // Number to put in rotateY()
        //cos-1((P122 + P132 - P232)/(2 * P12 * P13))
        //where P12 is the length of the segment from P1 to P2, calculated by
        //sqrt((P1x - P2x)2 + (P1y - P2y)2)

        if (x < centerX) {
            torsoRotate *= -1;
        }
        return torsoRotate.floatValue();
    }


So for touch events I do this:


@Override
    public boolean onTouchEvent(MotionEvent me) {
        if (me.getAction() == MotionEvent.ACTION_DOWN) {
            holdType = 0;
            windowX = me.getX();
            windowY = me.getY();
            if (inGame) {
                ///If it's in the dpad
                //
                if (dpadShoot.touched(windowX, windowY)) {
                    holdType = 1;
                }
            }
            return true;
        }

        if (me.getAction() == MotionEvent.ACTION_UP) {
           
            return true;
        }

        if (me.getAction() == MotionEvent.ACTION_MOVE) {
            if (holdType == 1) {
                    Object3D.clearRotation(); //clear the rotation of the model
                    Object3D.rotateY(computeRadian(me.getX(), me.getY())); //compute the rotation based on the X and Y given from the touchpad
            }
            return true;
        }
        try {
            Thread.sleep(15);
        } catch (Exception e) {
        }
        return super.onTouchEvent(me);
    }



Please note, the second bit of code won't work, I just pulled what I have, removed most of it, and put in some sample code. But the first method I posted took me a good solid two days and no sleep to figure out, and it's flawless, so enjoy.
#8
This is a work in progress, so any progress I get I'll post.

I am working on making three menus right now, one that's called at the game start and when you're not in game, one that's called while in the game and you hit the settings button on the android phone( this one will contain things like 'End Game', 'Change Settings', etc) and the last menu object will be a settings menu, that's called when you select 'Change Settings'

#9
Support / Code example to build your own GUI menu
June 30, 2011, 11:43:22 PM
Hey everyone, I dunno how helpful this could be but I had a heck of a time getting the concept down so I'll release some working code that I believe to be a great example. My original goal was a menu system before ever loading map and or player models and all the stuff needed for a game (this also works for loading screens if used right) so it's a lil complex for the simplicity I was looking for but still more simple than using Nifty GUI (at least for me) and I think the overhead should be less as well, anyway to the code:


Setting up the object:
This is an example of a game menu, it's a small black box that is centered and only uses a portion of the screen

                gameMenu = new Menu(GameHeight, GameWidth); //always pass in the game's width and height, It seems a little arbitrary but it feels effecient
                gameMenu.Width = 128; //These define the size of the menu it's self, anything behind this will be show (for example the rendered world)
                gameMenu.Height = 160;
                gameMenu.X = Menu.CENTER;
                gameMenu.Y = Menu.CENTER;
                gameMenu.build();
                Texture gameMenuButtonTexture = new Texture(BitmapFactory.decodeResource(getResources(), R.raw.gamemenu));
                //gameMenu.addButton("name", width, height, destX, destY, srcX, srcY, textureImage)
                gameMenu.addElement("quit", 128, 20, Menu.CENTER, 16, 1, 1, gameMenuButtonTexture);
                gameMenu.addElement("mainmenu", 128, 20, Menu.CENTER, 66, 0, 30, gameMenuButtonTexture);
                gameMenu.addElement("settings", 128, 20, Menu.CENTER, 122, 0, 66, gameMenuButtonTexture);

You must do gameMenu.show = true; before calling gameMenu.draw(framebuffer) will do anything.


This is an example of a main menu, the type of menu that fills the entire screen, when this is active, you don't need to render the world

                mainMenu = new Menu(GameHeight, GameWidth);
                Texture start_button = new Texture(BitmapFactory.decodeResource(getResources(), R.raw.startgame)); //load image for element.
                //mainMenu.addButton("name", width, height, destX, destY, srcX, srcY, textureImage) //Variables are very similar jPCT's blit
                mainMenu.addElement ("start", 128, 14, Menu.CENTER, Menu.CENTER, 1, 1, start_button);
                mainMenu.build(); //required in every instance at least once
                mainMenu.show = true;


I call this right before my  FrameBuffer.display(); As far as I'm aware this is the best spot to call a blit.
Don't do any checks against this, instead check against Menu.show

mainMenu.draw(framebuffer);
gameMenu.draw(framebuffer);


And if you want to check against an element getting touched:

@Override
public boolean onTouchEvent(MotionEvent me) {
    if (me.getAction() == MotionEvent.ACTION_DOWN) {
         String menuSelect = gameMenu.checkTouch(me.getX(), me.getY());  //By supplying X and Y you will get a string name of the element
         //TODO: put gameMenu.show check inside of checkTouch
         if("start".equals(menuSelect) && gameMenu.show){ //If the start portion was touched (and the menu is currently showing)
                Logger.log("start element was touched!"); //Do something about it
         }
    }
}



This is the menu class:

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package edak.moon.scape;


import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Color;

import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Texture;
import com.threed.jpct.Logger;

/**
*
* @author Kade
*/
public class Menu {
    //NOTE: If you don't otherwise specify, menu will assume it's covering the entire game
    public int Width;
    public int Height;
    public int gameWidth;
    public int gameHeight;
   
    public boolean show = false;
   
    //Assumes the menu starts in the top left corner
    public int X = 1;
    public int Y = 1;
   
    public Element[] elements = new Element[10];
    private int elementCount = 0;
   
    //Assumes you want to color the menu a solid color, set a bitmap here otherwise
    private Bitmap backgroundImage = null;
    //Assumes that color is black
    private int backgroundColor = Color.BLACK;
   
    //After the bitmap has been created with paint, this texture is what's rendered
    //I believe I'm going to remove the need for Paint and Canvas soon, and just require texture friendly sizes.
    private Texture menuTexture;
   
    //Static for center, I assumed this required a value;
    static int CENTER = 99000;
   
    //The menu's only requirements are the game's width and height in pixels
    public Menu(int GameHeight, int GameWidth){
        gameHeight = GameHeight;
        gameWidth = GameWidth;
        Height = GameHeight;
        Width = GameWidth;
    }
   
   
   
    //Build constructs the menu's background
    public void build(){
        backgroundImage = null;
        build(null);
    }
   
    //if you supply a background image you must give a paint object
    public void build(Paint paint){
        Bitmap bitmap = Bitmap.createBitmap(1024, 1024, Bitmap.Config.ARGB_4444);
        if(backgroundImage != null){
            Canvas canvas = new Canvas(bitmap);
            canvas.drawBitmap(backgroundImage, 0, 0, paint);
        }else{
            bitmap.eraseColor(backgroundColor);
        }
        menuTexture = new Texture(bitmap);
        FixXY();
    }
   
    public void draw(FrameBuffer fb){
        if(show){
            //Take the created background and show it first (remember this is either a solid color or some supplied background image)
            fb.blit(menuTexture, 1, 1, X, Y, Width, Height, false);
            //Then draw each element on top of it. This is set up so that each element is a texture (or part of a texture) so they can be
                //manipulated in real time
            for(int i = 0; i < elementCount; i++){
                elements[i].Blit(fb);
            }
        }
    }
   

      ///I know fixXY is in buttons too but the approach is different enough that seperate functions are needed
    ///This is for aligning the menu in the game screen, supplying negative values offests from the opposite side
    ///if you don't set gameHeight or gameWidth it will assume the menu you're supplying covers the entire screen
        public void FixXY(){
            if(X == Menu.CENTER){
                X = (gameWidth/2)-(Width/2);
            }               
            if(Y == Menu.CENTER){
                Y = (gameHeight/2)-(Height/2);
            }
        }
   
    ///This is the most annoying part of adding an element, but it's pretty straight forward
        //name: whatever you want for the element, also used against touch events
        //width and height: the size of the final element you want on screen
            ///this determins the touch size if you use this as a button
            //this also determins what on the source bitmap is copied
        //destX destY: where on the menu to place this button it's relative to the menu size and placement
        //srcX srcY: the texture image you are blitting, where in that texture do you want to start copying the element
    public void addElement(String name, int width, int height, int destX, int destY, int srcX, int srcY, Texture image){
        //I read a long page about performance in Android and I specifically remember
            //setting the variable directly is faster than a getter or a setter so hey might as well do what I can
        elements[elementCount] = new Element(name);
        elements[elementCount].image = image;
        elements[elementCount].width = width;
        elements[elementCount].height = height;
        elements[elementCount].destX = destX;
        elements[elementCount].destY = destY;
        elements[elementCount].srcX = srcX;
        elements[elementCount].srcY = srcY;
        elements[elementCount].Width = Width;
        elements[elementCount].Height = Height;
        elements[elementCount].X = X;
        elements[elementCount].Y = Y;
        elements[elementCount].fixXY();
        elementCount++;
    }
   
   
    public Element elementByName(String name){
        for(int i=0;i < elementCount; i++){
            if(elements[i].name.equals(name)){
                return elements[i];
            }
        }
        return null;
    }
   
   
    ///This goes in onTouchEvent and you pass it the touched X and Y
        //returns the name of the set element that was touched, otherwise null
    public String checkTouch(float x, float y){
        for(int i=0;i < elementCount; i++){
            if(elements[i].touched(x, y)){
                return elements[i].name;
            }
        }
        return null;
    }
   
    public class Element {
        public String name;
        public int width;
        public int height;
        public int destX;
        public int destY;
        public int srcX;
        public int srcY;
        public int Height;
        public int Width;
        public int X;
        public int Y;
        public Texture image = null;
        public boolean show = true;
        //public int Color = null;
       
       
        //Every element is required a name
        public Element(String Name){
            name = Name;
        }
       
        public void Blit(FrameBuffer fb){
            if(show){
                fb.blit(image, srcX, srcY, destX, destY, width, height, true);
            }
        }
       
       
        //Every element has the option to be used like a button by simply calling Menu.checkTouch(x, y) and looking for the element's name
        public boolean touched(float x, float y){
            if(x > this.destX-5 && x < this.destX+width+5 && y > this.destY-5 && y < this.destY+height+5){
                return true;
            }else{
                return false;
            }
        }
       
         ///By supplying negative x or y you can offset the image from the bottom of the screen vs the top
        //Also the option to supply Menu.CENTER_BUTTON
        ///TODO: Menu.CENTER_POS_X = inbetween the max X and the middle X ie centered between the center
        public void fixXY(){
            if(destX < 0){
                destX+= Width+X;
            }
            if( destY < 0){
                destY+= Height+Y;
            }
            if(destX == Menu.CENTER){
                destX = (X+(Width/2))-(width/2);
            }else{
                destX += X;
            }
            if(destY == Menu.CENTER){
                destY = (Y+(Height/2))-(height/2);
            }else{
                destY += Y;
            }
        }
    }
   
}


Any questions or comments welcome.

-I've done a bit of work on it today, now creating a menu that's not the entire size of the screen is possible
--Ok, I went through and cleared up a bunch of junk, buttons are now elements, and elements can have a touch event checked against them
---Added some comments and small fixes here and there
#10
Support / Re: Traceview error
June 30, 2011, 07:46:36 AM
I read someone fixed a similar issue by changing their rom, i'll look into this and let you know how it goes. Currently running a version of aospCMOD Ginger bread for VM670 so I'll try test on some other rom installs. Thanks
#11
Support / Traceview error
June 29, 2011, 07:11:02 AM
Hey!

Everytime I attempt to use traceview (be it from Eclipse or via command line) I get the following error:

ThreadData: 'com/threed/jpct/XXXXXXX' calltime XXXX is less than previous time XXXX for thread '[10] GLThread 11'

The thread at the end of the error is always the same, but depending where I start traceview in the code, ThreadData can change

I've searched everywhere and can't find anything on it. Any suggestions?
#12
Support / Re: Casting Rays for collision Detection
June 26, 2011, 12:58:01 AM
Excellent my mistake :-) Thanks.
#13
Support / Re: Casting Rays for collision Detection
June 26, 2011, 12:27:16 AM
Thanks but maybe I need to rephrase my question.

I want to cast a ray, what methods can I use?

I want to specify the start, and I want to specify a direction, then I want to get the first place in world space there's a collision detection.
#14
Support / Casting Rays for collision Detection
June 24, 2011, 09:25:10 PM
I want to cast a specific ray ( ie I supply origin and direction ) and collect the first point in world-space there was a collision at.

-I've implemented the collision listener to my class.

-I've done this:

public void collision(CollisionEvent ce){
        Logger.log("Detected");
        new SimpleVector CollisionPoint = ce.getFirstContact();
}

-I've applied Object3D.COLLISION_CHECK_OTHERS to the mesh I want to test.


Now how do I cast a ray from point A to point B and have it trigger the collision event? Thus outputting to the log Detected and setting CollsionPoint