void RenderableParticleEffectEntityItem::updateQuads(RenderArgs* args, bool textured) {
    float particleRadius = getParticleRadius();
    glm::vec4 particleColor(toGlm(getXColor()), getLocalRenderAlpha());
    
    glm::vec3 upOffset = args->_viewFrustum->getUp() * particleRadius;
    glm::vec3 rightOffset = args->_viewFrustum->getRight() * particleRadius;
    
    QVector<glm::vec3> vertices;
    QVector<glm::vec3> positions;
    QVector<glm::vec2> textureCoords;
    vertices.reserve(getLivingParticleCount() * VERTS_PER_PARTICLE);
    
    if (textured) {
        textureCoords.reserve(getLivingParticleCount() * VERTS_PER_PARTICLE);
    }
    positions.reserve(getLivingParticleCount());
   
    
    for (quint32 i = _particleHeadIndex; i != _particleTailIndex; i = (i + 1) % _maxParticles) {
        positions.append(_particlePositions[i]);
        if (textured) {        
            textureCoords.append(glm::vec2(0, 1));
            textureCoords.append(glm::vec2(1, 1));
            textureCoords.append(glm::vec2(1, 0));
            textureCoords.append(glm::vec2(0, 0));
        }
    }
        
    // sort particles back to front
    ::zSortAxis = args->_viewFrustum->getDirection();
    qSort(positions.begin(), positions.end(), zSort);
    
    for (int i = 0; i < positions.size(); i++) {
        glm::vec3 pos = (textured) ? positions[i] : _particlePositions[i];

        // generate corners of quad aligned to face the camera.
        vertices.append(pos + rightOffset + upOffset);
        vertices.append(pos - rightOffset + upOffset);
        vertices.append(pos - rightOffset - upOffset);
        vertices.append(pos + rightOffset - upOffset);
   
    }
    
    if (textured) {
        DependencyManager::get<GeometryCache>()->updateVertices(_cacheID, vertices, textureCoords, particleColor);
    } else {
        DependencyManager::get<GeometryCache>()->updateVertices(_cacheID, vertices, particleColor);
    }
}
//--------------------------------------------------------------
void testApp::update(){
	vidGrabber.grabFrame();	
	if (vidGrabber.isFrameNew()){
		int totalPixels = camWidth*camHeight*3;
		unsigned char * pixels = vidGrabber.getPixels();
		camImg.setFromPixels(pixels,camWidth,camHeight,OF_IMAGE_COLOR,true);
        if (((ofGetElapsedTimeMillis() - elapsedTime) > 10) && (keyPressed_Space || keyPressed_D || keyPressed_S || keyPressed_F)){
            finder.findHaarObjects(camImg);
            elapsedTime = ofGetElapsedTimeMillis();
        }
        
        //Particle system
        ps.run();
        
        if (keyPressed_Space){
            for(int i = 0; i < finder.blobs.size(); i++) {
                ofRectangle cur = finder.blobs[i].boundingRect;
                //ofRect(cur.x, cur.y, cur.width, cur.height);
                ofVec2f currentCentroid(finder.blobs[i].centroid.x,finder.blobs[i].centroid.y);
                ofVec2f faceVelocity(previousCentroid.x - currentCentroid.x,previousCentroid.y - currentCentroid.y);
                
                //If you shake your head the particles go away
                if (currentCentroid.distance(previousCentroid) > 5){
                    spawnRate *= 0.55;
                }
                else{
                    spawnRate *= ofRandom(1.0,5.0);
                }
                //clamp it to something reasonable
                spawnRate = MIN(MAX(spawnRate,1),100);
                
                for(int j = 0; j < spawnRate; j++){
                    ofVec2f accel;
                    ofVec2f velocity;
                    ofVec2f location;
                    float radius = ofRandom(3,8);
                    velocity.set(0,0);
                    
                    //Make the particles dynamic in this case
                    if (keyPressed_A){
                        accel.set(0,0.5);
                        velocity.set(0,-1);
                        velocity -= (faceVelocity*0.8);
                    }
                    else{
                        accel.set(0.0,0.0);
                    }

                    location.set(int(currentCentroid.x + ofRandom(-cur.width,cur.width)*0.5),int(currentCentroid.y + ofRandom(-cur.height,cur.height)*0.5));
                    int colorIndex = (location.y * camWidth + location.x-1)*3;
                    int distanceAlphaValue = ofClamp((255 - (location.distance(currentCentroid) / (cur.width*0.5)) * 255),0,255);
                    ofColor particleColor(pixels[colorIndex],pixels[colorIndex+1],pixels[colorIndex+2],distanceAlphaValue);
                    //ofColor particleColor(ofRandom(128,255),0,0);
                    Particle newParticle(accel,velocity,location,radius,particleColor);
                    ps.addParticle(newParticle);
                }
                previousCentroid.set(finder.blobs[i].centroid.x,finder.blobs[i].centroid.y);
            }
        }
	}
}