Tuesday, February 5, 2013

Finally some finger friction (week 4 progress)


 New touch system
Turns out the system I was using for touch, the same one which worked flawless for my previous project, was impossible (for the most part) to use in this project.
What the system was, was a queue-based one. Each touch triggered a touch event (normal action), the event was then translated into a touch object (my code), and added to the back of a queue (also my code). The problem with this is that multiple users were not being detected. My previous post about the pointer ID's was correct in how they work...but when removing a touch, the system didn't recognize it. Then there was crashes about syncing, which was just beyond my logic.

The new touch system sends the x/y location (in screen coordinates) straight to static variables (always visible everywhere in the program), and they are all processed each update phase of the program (regardless if there was a new touch event for that finger or not). Although this process prevents a full stream of data from x1/y1 to x2/y2, it does represent the most up to date point location and prevents a flood of old data from filling the screen with particle emitters.

Currently, all the touch points are visible, no delay is shown (besides the render update delay), and the system recognizes when a touch is active or not.

My fingers, all visible and colory


Dead/alive/dieing Particle System

After deciding that each user was going to have their own particle systems (to ease the yet-to-be-added settings menu integration) and coding the initialization/ setup in the user class, I found an interesting problem. The particle system automatically generates a large amount of particle at the beginning and starts moving them around. When the particle's life expires, it respawns at the emitter's location....but the particle never truly dies, even when the user removes their touch. So, this had to be fixed (now that the system can recognize when the user removes a touch).

public void Update()
{
    boolean sUpdate = false;
   
    for(int i = 0; i < 10; i++)
    {
        if(Users[i].State == 1)
        {// a touch was added or is still active
            Users[i].InitSystem(world);
            Users[i].Update();
            //Move(Users[i]);
            sUpdate = true;
        }
       
        if(Users[i].State == 2)
        {// user removed a touch
            if(!Users[i].isDieing())
            {// if it's not dieing, then kill it
                Users[i].Kill();
                Users[i].Update();
            } else
            {// waiting for the last few particles to die
                Users[i].Update();
            }
           
            if(Users[i].State == 0)
            Log.i(TAG, "Removed user: " + i);
            sUpdate = true;
        }
    }
   
    Update = sUpdate;
}
InitSystem(): sends the current 3D world to the particle system so each system can handle adding/removing 3D objects on it's own.
Update(): Updates the current location of the pointer in the system (the Users[i] variable contains the touch location already and the particle system), moves active particles, and advances the stages of any active particles (color, velocity, life cycle).
Kill(): tells the particle system to not re-new any dead particles. The particle system also checks each update cycle if all the particles are dead yet or not.
isDieing(): returns if the particle system is in the process of dieing "return (particles.State == 2);"

The following is the Update(x,y) code which is called in the Users[i].Update() function

    public void Update(int x, int y)
    {
        this.x = x;// update the new location of where
        this.y = y;// new particles will spawn
      
        boolean dead = true;
      
        for (int i = 0; i < particles.length; i++)
        {
            Particle p = particles[i];
            if (p.lifetime <= 0)
            {
                if(p.lifetime == -1)
                    continue;// the particle is dead, so don't touch it
              
                if(State >= 2)
                {// don't make any new particle, preparing to kill this system
                    world.removeObject(p.object);
                    p.lifetime = -1;
                    continue;
                }
              
                // revive this particle
                newParticle(p);
            }
            dead = false;
          
            p.move();
          
            p.color.Decay(decay);// needs an update for using a color array
            if (p.color.RGB() < 0)
                p.color.Set(0);
            p.UpdateColor();
        }
      
        if(State == 2 && dead)
            State = 3;
    }
Ano
ther type of float?
I've also been reading about how integers with bit shifted values are faster to use than float values and I'm in the progress of testing this.
Example:
Instead of
float px = 15.82673;
it would become
int  px = 20 << 8; // which becomes 5120 in code
adding gravity to the variable would be normal, "px += vx;". But when using the variable to draw it to the screen, it will be right shifted back to normal.
int px, py;
Init()
{
    px = py = 100 << 8;// which becomes 25600 in code
}
loop()
{
    px += vx;// vx is accumulative
    vx += particles.gravity;
    Draw();
}
Draw()
{
    world.draw(particle.image, px >> 8, py >> 8);
}
Advantage:
- It has decimal like values while not needing to have a "(int)" before being used in int only functions
- Incrementing/ decrementing the value works the same as how a normal float would

Disadvantage:
- Reducing the total amount of values the variable can hold. A signed int after being bit shifted has a max value of 256 (due to java using only signed ints), while a float (with decimal places) is "2127"



Current progress actions

The thing I'm still working on now are getting the billboard action of each particle working....well, I only need to get the class working, everything else just falls into place. Currently, it all looks correct enough for testing, but I've yet to have time to test the app (due to making tweaks to the code and working on a project for another class).

No comments:

Post a Comment