bool Emitter::addParticle(){ particle *newParticle; GLfloat start[4]; GLfloat end[4]; float speed; //Particle pool exists and max num particles not exceeded if(e != NULL && managerParticleList != NULL && e->particleCount < e->totalParticles){ newParticle = managerParticleList; managerParticleList = managerParticleList->next; if(e->particleList != NULL){ e->particleList->prev = newParticle; } newParticle->next = e->particleList; newParticle->prev = NULL; e->particleList = newParticle; newParticle->pos.x = randDist()/20; newParticle->pos.y = 0; newParticle->pos.z = 0; newParticle->prevPos.x = 0; newParticle->prevPos.y = 0; newParticle->prevPos.z = 0; //Calculate direction vector //yaw = e->yaw + (e->yawVar*randDist()); //pitch = e->pitch + (e->pitchVar*randDist()); //rotationToDirection(pitch, yaw, &newParticle->dir); newParticle->dir = e->dir + (e->dirVar*randDist()); speed = e->speed + (e->speed * randDist()); newParticle->dir.x *= speed; newParticle->dir.y *= speed; newParticle->dir.z *= speed; start[0] = e->startColor[0] + (e->startColorVar[0] * randDist()); start[1] = e->startColor[1] + (e->startColorVar[1] * randDist()); start[2] = e->startColor[2] + (e->startColorVar[2] * randDist()); end[0] = e->endColor[0] + (e->endColorVar[0] * randDist()); end[1] = e->endColor[1] + (e->endColorVar[1] * randDist()); end[2] = e->endColor[2] + (e->endColorVar[2] * randDist()); newParticle->color[0] = start[0]; newParticle->color[1] = start[1]; newParticle->color[2] = start[2]; newParticle->life = e->life + (int)((float)e->lifeVar * randDist()); newParticle->deltaColor[0] = (end[0] - start[0]) / newParticle->life; newParticle->deltaColor[1] = (end[1] - start[1]) / newParticle->life; newParticle->deltaColor[2] = (end[2] - start[2]) / newParticle->life; e->particleCount++; return true; } return false; }
bool circleEmitter::addParticle(){ particle *newParticle; float speed; //Particle pool exists and max num particles not exceeded if(e != NULL && *managerParticleList != NULL && e->particleCount < e->totalParticles && emitting){ newParticle = *managerParticleList; *managerParticleList = (*managerParticleList)->next; if(e->particleList != NULL){ e->particleList->prev = newParticle; } newParticle->next = e->particleList; newParticle->prev = NULL; e->particleList = newParticle; float angle = randomAngle(); float radScalar = randDist(); newParticle->rand = radScalar; newParticle->radius = radius * radScalar; STVector3 point = STVector3(radius*radScalar*cosf(angle), 0, radius*radScalar*sinf(angle)); STVector3 straightUp = STVector3(0,1,0); STVector3 circleDir = STVector3(e->dir.x, e->dir.y, e->dir.z); STVector3 a = STVector3::Cross(straightUp, circleDir); float w = sqrt(powf(straightUp.Length(), 2) * powf(circleDir.Length(), 2)) + STVector3::Dot(straightUp, circleDir); Quaternion rotateCircle = Quaternion(w, a.x, a.y, a.z); rotateCircle.Normalize(); STVector3 rotatedPoint = rotateCircle.rotate(point, rotateCircle); newParticle->pos.x = rotatedPoint.x + e->pos.x; newParticle->pos.y = rotatedPoint.y + e->pos.y; newParticle->pos.z = rotatedPoint.z + e->pos.z; /* newParticle->pos.x = e->pos.x + radius*sinf(angle); newParticle->pos.y = e->pos.y; newParticle->pos.z = e->pos.z + radius*cosf(angle); */ newParticle->prevPos.x = 0; newParticle->prevPos.y = 0; newParticle->prevPos.z = 0; newParticle->dir = e->dir + (e->dirVar*randDist()); speed = e->speed + (e->speed * randDist()); newParticle->dir.x *= speed; newParticle->dir.y *= speed; newParticle->dir.z *= speed; newParticle->life = e->life + (int)((float)e->lifeVar * randDist()); newParticle->side = randDist(); e->particleCount++; return true; } return false; }
bool Emitter::addParticle(){ particle *newParticle; float speed; //Particle pool exists and max num particles not exceeded if(e != NULL && *managerParticleList != NULL && e->particleCount < e->totalParticles){ newParticle = *managerParticleList; *managerParticleList = (*managerParticleList)->next; if(e->particleList != NULL){ e->particleList->prev = newParticle; } newParticle->next = e->particleList; newParticle->prev = NULL; e->particleList = newParticle; newParticle->pos.x = e->pos.x; newParticle->pos.y = e->pos.y; newParticle->pos.z = e->pos.z; newParticle->prevPos.x = 0; newParticle->prevPos.y = 0; newParticle->prevPos.z = 0; //Calculate direction vector //yaw = e->yaw + (e->yawVar*randDist()); //pitch = e->pitch + (e->pitchVar*randDist()); //rotationToDirection(pitch, yaw, &newParticle->dir); newParticle->dir = e->dir + (e->dirVar*randDist()); speed = e->speed + (e->speed * randDist()); newParticle->dir.x *= speed; newParticle->dir.y *= speed; newParticle->dir.z *= speed; newParticle->life = e->life + (int)((float)e->lifeVar * randDist()); newParticle->side = randDist(); e->particleCount++; return true; } return false; }
bool windCircleEmitter::updateParticle(particle *p){ if(p != NULL && p->life > 0){ p->prevPos.x = p->pos.x; p->prevPos.y = p->pos.y; p->prevPos.z = p->pos.z; p->dir = p->dir*(fmax((p->life),e->life/1.1)/(float)e->life); p->pos.x += p->dir.x; p->pos.y += p->dir.y; p->pos.z += p->dir.z; //p->dir.x += e->force.x*cosf(p->pos.y)*p->side; //p->dir.y += e->force.y*cosf(p->pos.y)*p->side; //p->dir.z += e->force.z*cosf(p->pos.y)*p->side; //p->dir.y += p->pos.z * p->pos.x / 20 * randDist(); //p->dir.z += p->pos.y * p->pos.x / 20 * randDist(); p->dir.y += p->pos.z * p->pos.x / 20 * randDist(); p->dir.z += p->pos.y * p->pos.x / 20 * randDist(); p->life--; return true; }else if(p != NULL && p->life == 0){ if(p->prev != NULL){ p->prev->next = p->next; }else{ e->particleList = p->next; } if(p->next != NULL){ p->next->prev = p->prev; } p->next = *managerParticleList; p->prev = NULL; *managerParticleList = p; e->particleCount--; } return false; }
void Emitter::display(){ for(int newP = 0; newP < (e->emitsPerFrame + e->emitVar*randDist()); newP++){ addParticle(); } glPointSize(2); glBegin(GL_POINTS); particle *curr = e->particleList; while(curr){ glVertex3f(curr->pos.x, curr->pos.y, curr->pos.z); curr = curr->next; } glEnd(); }
bool Emitter::addParticle(){ particle *newParticle; float speed; //Particle pool exists and max num particles not exceeded if(e != NULL && *managerParticleList != NULL && e->particleCount < e->totalParticles && emitting){ newParticle = *managerParticleList; *managerParticleList = (*managerParticleList)->next; if(e->particleList != NULL){ e->particleList->prev = newParticle; } newParticle->next = e->particleList; newParticle->prev = NULL; e->particleList = newParticle; newParticle->pos.x = e->pos.x; newParticle->pos.y = e->pos.y; newParticle->pos.z = e->pos.z; newParticle->prevPos.x = 0; newParticle->prevPos.y = 0; newParticle->prevPos.z = 0; newParticle->dir = e->dir + (e->dirVar*randDist()); speed = e->speed + (e->speed * randDist()); newParticle->dir.x *= speed; newParticle->dir.y *= speed; newParticle->dir.z *= speed; newParticle->life = e->life + (int)((float)e->lifeVar * randDist()); newParticle->side = randDist(); e->particleCount++; return true; } return false; }
void Emitter::display(){ std::cout << "Adding " << e->particleCount << std::endl; for(int newP = 0; newP < (e->emitsPerFrame + e->emitVar*randDist()); newP++){ addParticle(); } glPointSize(2); glBegin(GL_POINTS); particle *curr = e->particleList; while(curr){ glColor4fv(curr->color); glVertex3f(curr->pos.x, curr->pos.y, curr->pos.z); curr = curr->next; } glEnd(); }
void Emitter::display(){ if(!displaying) return; pthread_mutex_lock(&mutex); if(!playFromFile){ for(int newP = 0; newP < (e->emitsPerFrame + e->emitVar*randDist()); newP++){ addParticle(); } } glPointSize(2); glBegin(GL_POINTS); particle *curr = e->particleList; while(curr){ glVertex3f(curr->pos.x, curr->pos.y, curr->pos.z); curr = curr->next; } glEnd(); pthread_mutex_unlock(&mutex); }
void windCircleEmitter::display(){ for(int newP = 0; newP < (e->emitsPerFrame + e->emitVar*randDist()); newP++){ addParticle(); } glEnable(GL_POINT_SMOOTH); glEnable( GL_TEXTURE_2D ); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); glEnable(GL_BLEND); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvf( GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE ); glBindTexture(GL_TEXTURE_2D, 0); //sf::Image::Bind(); //or glBindTexture(id); glEnable(GL_POINT_SPRITE); glDepthMask(GL_FALSE); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); // File locations std::string vertexShader = "/Users/aarondamashek/Documents/Stanford Work/Spring 2013/CS 248/ParticleSystem3/Particles/kernels/default.vert"; std::string fragmentShader = "/Users/aarondamashek/Documents/Stanford Work/Spring 2013/CS 248/ParticleSystem3/Particles/kernels/wind.frag"; //std::string fragmentShader = "/Users/aarondamashek/Documents/Stanford Work/Spring 2013/CS 248/ParticleSystem3/ProgrammableShading/kernels/wind.frag"; std::string windPic = "/Users/aarondamashek/Documents/Stanford Work/Spring 2013/CS 248/ParticleSystem3/Particles/wind.png"; STImage *windImg; STTexture *windTex; STShaderProgram *shader; windImg = new STImage(windPic); windTex = new STTexture(windImg); shader = new STShaderProgram(); shader->LoadVertexShader(vertexShader); shader->LoadFragmentShader(fragmentShader); // Texture 1: fire glActiveTexture(GL_TEXTURE0); windTex->Bind(); // Bind the textures we've loaded into openGl to // the variable names we specify in the fragment // shader. shader->SetTexture("windTex", 0); // Invoke the shader. Now OpenGL will call our // shader programs on anything we draw. shader->Bind(); shader->SetUniform("pointRadius", 7.0f); shader->SetUniform("point_size", 7.0f); glPointSize(5); glBegin(GL_POINTS); particle *curr = e->particleList; while(curr){ glVertex3f(curr->pos.x, curr->pos.y, curr->pos.z); curr = curr->next; } glEnd(); glDisable(GL_POINT_SPRITE); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); glDepthMask(GL_TRUE); glDisable(GL_POINT_SMOOTH); shader->UnBind(); glActiveTexture(GL_TEXTURE0); windTex->UnBind(); delete windImg; delete windTex; delete shader; }
// runs in O(n log t) time where n is the input number of sentences and t is the number of tokens in the input corpus std::string rawr::randomSentence(int maxL, std::mt19937& rng) const { if (!_compiled) { return ""; } std::string result; kgram cur(1, wildcardQuery); int cuts = 0; std::stack<parentype> open_delimiters; std::set<int> used_corpora; for (;;) { if (cur.size() == _maxK) { cur.pop_front(); } while (cur.size() > 2 && cuts > 0 && !std::bernoulli_distribution(1.0 / static_cast<double>(cuts))(rng)) { cur.pop_front(); cuts--; } // Gotta circumvent the last line of the input corpus // https://twitter.com/starla4444/status/684222271339237376 if (_stats.count(cur) == 0) { // The end of a corpus should probably be treated like a terminator, so // maybe we should just end here. if (result.length() > maxL || std::bernoulli_distribution(1.0 / 4.0)(rng)) { break; } cur = kgram(1, wildcardQuery); } auto& distribution = _stats.at(cur); int max = distribution.rbegin()->first; std::uniform_int_distribution<int> randDist(0, max - 1); int r = randDist(rng); const token_data& next = distribution.upper_bound(r)->second; const token& interned = _tokenstore.get(next.tok); std::string nextToken = interned.w.forms.next(rng); // Apply user-specified transforms if (_transform) { nextToken = _transform(interned.w.canon, nextToken); } // Determine the casing of the next token. We randomly make the token all // caps based on the markov chain. Otherwise, we check if the previous // token is the end of a sentence (terminating token or a wildcard query). std::uniform_int_distribution<int> caseDist(0, next.all - 1); int casing = caseDist(rng); if (casing < next.uppercase) { std::transform( std::begin(nextToken), std::end(nextToken), std::begin(nextToken), ::toupper); } else { bool capitalize = false; if (casing - next.uppercase < next.titlecase) { capitalize = true; } else if (cur.rbegin()->type == querytype::sentence) { if (std::bernoulli_distribution(1.0 / 2.0)(rng)) { capitalize = true; } } else { const token& lastTok = _tokenstore.get(cur.rbegin()->tok); if (lastTok.suffix == suffixtype::terminating && std::bernoulli_distribution(1.0 / 2.0)(rng)) { capitalize = true; } } if (capitalize) { nextToken[0] = toupper(nextToken[0]); } } // Delimiters for (auto& dt : interned.delimiters) { if (dt.first.status == doublestatus::both) { switch (dt.first.type) { case parentype::paren: nextToken = std::string("(", dt.second) + nextToken + std::string(")", dt.second); break; case parentype::square_bracket: nextToken = std::string("[", dt.second) + nextToken + std::string("]", dt.second); break; case parentype::asterisk: nextToken = std::string("*", dt.second) + nextToken + std::string("*", dt.second); break; case parentype::quote: nextToken = std::string("\"", dt.second) + nextToken + std::string("\"", dt.second); break; } } else if (dt.first.status == doublestatus::opening) { for (int i=0; i<dt.second; i++) { open_delimiters.push(dt.first.type); } switch (dt.first.type) { case parentype::paren: nextToken = std::string("(", dt.second) + nextToken; break; case parentype::square_bracket: nextToken = std::string("[", dt.second) + nextToken; break; case parentype::asterisk: nextToken = std::string("*", dt.second) + nextToken; break; case parentype::quote: nextToken = std::string("\"", dt.second) + nextToken; break; } } else if (dt.first.status == doublestatus::closing) { for (int i=0; i<dt.second; i++) { while (!open_delimiters.empty() && (open_delimiters.top() != dt.first.type)) { switch (open_delimiters.top()) { case parentype::paren: nextToken.append(")"); break; case parentype::square_bracket: nextToken.append("]"); break; case parentype::asterisk: nextToken.append("*"); break; case parentype::quote: nextToken.append("\""); break; } open_delimiters.pop(); } if (open_delimiters.empty()) { switch (dt.first.type) { case parentype::paren: result = "(" + result; break; case parentype::square_bracket: result = "[" + result; break; case parentype::asterisk: result = "*" + result; break; case parentype::quote: result = "\"" + result; break; } } else { open_delimiters.pop(); } switch (dt.first.type) { case parentype::paren: nextToken.append(")"); break; case parentype::square_bracket: nextToken.append("]"); break; case parentype::asterisk: nextToken.append("*"); break; case parentype::quote: nextToken.append("\""); break; } } } } // Terminators if (interned.suffix == suffixtype::terminating) { auto term = interned.w.terms.next(rng); nextToken.append(term.form); if (term.newline) { nextToken.append("\n"); } else { nextToken.append(" "); } } else if (interned.suffix == suffixtype::comma) { nextToken.append(", "); } else { nextToken.append(" "); } if (next.all == max) { // If this pick was guaranteed, increase cut chance cuts++; } else if (cuts > 0) { // Otherwise, decrease cut chance cuts /= 2; } if (next.corpora.size() == 1) { used_corpora.insert(*next.corpora.begin()); } /* DEBUG */ std::cout << cur << "-> \"" << nextToken << "\" (" << next.all << "/" << max << ")" << " in corp"; for (auto cor : next.corpora) { std::cout << " " << cor; } std::cout << "; l=" << cur.size() << ",cuts=" << cuts << std::endl; cur.push_back(next.tok); result.append(nextToken); if (interned.suffix == suffixtype::terminating && (result.length() > maxL || std::bernoulli_distribution(1.0 / 4.0)(rng))) { break; } } // Ensure that enough corpora are used if (used_corpora.size() < _min_corpora) { return randomSentence(maxL, rng); } // Remove the trailing space if (result.back() == ' ' || result.back() == '\n') { result.pop_back(); } // Close any open delimiters while (!open_delimiters.empty()) { switch (open_delimiters.top()) { case parentype::paren: result.append(")"); break; case parentype::square_bracket: result.append("]"); break; case parentype::asterisk: result.append("*"); break; case parentype::quote: result.append("\""); break; } open_delimiters.pop(); } return result; }