/// return a 0-1 float or a -.5 to .5 float? double perlinNoise(float x) { return ( perlinNoise(x,128) + 0.5*perlinNoise(x,64) + 0.2*perlinNoise(x,32) + 0.06*perlinNoise(x,16) ); }
inline void benchParallel(rgba* image){ omp_set_num_threads(THREADS); DomaineMaths domain(0, 0, DIM_W, DIM_H); const float dx = (float) (domain.dx / (float) DIM_W); const float dy = (float) (domain.dy / (float) DIM_H); float t = 1; #pragma omp parallel { int tid = omp_get_thread_num(); int i = tid + 1; float y = domain.y0 + tid * dy; while(i <= DIM_W){ float x = domain.x0; for(int j = 1; j <= DIM_H; ++j){ float c = perlinNoise(x,y, 1); setFloatRGBA(image, i, j, 135, 206, 250, c * 255.0); x += dx; } y += THREADS * dy; i += THREADS; } } }
void PerlinImageOMP::refreshAll(const DomaineMaths& domainNew){ const int w = getW(); const int h = getH(); const float dx = (float) (domainNew.dx / (float) w); const float dy = (float) (domainNew.dy / (float) h); #pragma omp parallel { int tid = omp_get_thread_num(); int i = tid + 1; float y = domainNew.y0 + tid * dy; while(i <= h){ float x = domainNew.x0; for(int j = 1; j <= w; ++j){ float c = perlinNoise(x,y,t); setRGBA(i, j, 135, 206, 250, c * 255.0); x += dx; } y += THREADS * dy; i += THREADS; } } }
Float Noise::turbulence(const Point &p, const Vector &dpdx, const Vector &dpdy, Float omega, int maxOctaves) { // Compute number of octaves for antialiased FBm Float s2 = std::max(dpdx.lengthSquared(), dpdy.lengthSquared()); Float foctaves = std::min((Float) maxOctaves, 1.f - .5f * log2(s2)); int octaves = (int) foctaves; // Compute sum of octaves of noise for turbulence Float sum = 0., lambda = 1., o = 1.; for (int i = 0; i < octaves; ++i) { sum += o * std::abs(perlinNoise(lambda * p)); lambda *= 1.99f; o *= omega; } Float partialOctave = foctaves - octaves; sum += o * smoothStep(.3f, .7f, partialOctave) * std::abs(perlinNoise(lambda * p)); return sum; }
double turbulenceAbs(int octaves, const Point& p, double lacunarity, double gain) { double sum = 0; double scale = 1; double totalgain = 1; for(int i=0;i<octaves;i++){ sum += totalgain*fabs(perlinNoise(Point(p.x()*scale, p.y()*scale, p.z()*scale))); scale *= lacunarity; totalgain *= gain; } return sum; }
/// Computes all octaves values for a coordinate float Perlin::pixelOctaves(float x, float y, float z) { float total = 0; // Sum of all octaves float freq = 1; // freq = 2^oct float amp = 1; // amp = persistence^oct float max = 0; // Stores the total amplitude to normalize the result for (int i = 0; i<numOctaves; i++) { total += perlinNoise(x * freq, y * freq, z* freq) * amp; max += amp; amp *= persistence; freq *= 2.0f; } return total / max; // Normalize the result }
Texture* genTexture(int seed) { Texture *tex = new Texture(); tex->sizeX = TEX_X; tex->sizeY = TEX_Y; tex->data = new unsigned char[TEX_X*TEX_Y * 3]; for (int i = 0; i < TEX_Y; i++) { for (int j = 0; j < TEX_X; j++) { unsigned char value = LEVEL*perlinNoise(float(j+seed)/16, float(i+seed)/16); tex->data[(j + i*TEX_X) * 3] = 0; tex->data[(j + i*TEX_X) * 3 + 1] = 0; tex->data[(j + i*TEX_X) * 3 + 2] = value; } } return tex; }
SDL_Surface* PerlinNoise::Render_Clouds(const int x, const int y, const int z, const int w, const int h, const double zoom, const double p) { const SDL_PixelFormat& fmt = *(screen->format); SDL_Surface* ret = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, fmt.BitsPerPixel, fmt.Rmask,fmt.Gmask,fmt.Bmask,fmt.Amask); for(int yi = 0; yi<h; yi++) { for(int xi = 0; xi<w; xi++) { int color= (int)(perlinNoise(x+xi, y+yi, z, zoom, p)*255); if(color>255) color=255; if(color<0) color=0; Uint32 pixel = SDL_MapRGB(ret->format, color, color, color); put_pixel32(ret,xi,yi,pixel); } } return ret; }
void initNoise() { logi.log("Creating noise"); int width,height; width = 1000; height = 1000; Texture perlinNoise(NOISE_TEXTURE,width,height); float* data = new float[width*height]; glm::vec2 w = glm::vec2(10.f); glm::mat2 rotMat1 = glm::mat2(cos(20.f),-sin(20.f),sin(20.f),cos(20.f)); for (int i = 0;i<width;i++) for (int j = 0;j<height;j++) { glm::vec2 p = 10.f*glm::vec2(i/float(width),j/float(height)); data[i*width+j] = 0.5*(glm::perlin(p,w)+0.5*glm::perlin(2.f*rotMat1*p,w*2.f)+0.25*glm::perlin(4.f*p,w*4.f)+0.125*glm::perlin(rotMat1*p*8.f,w*8.f)); } perlinNoise.loadBumpData(data); perlinNoise.toTGA("noise.tga"); perlinNoise.load(); }
inline void benchSequential(rgba* image){ DomaineMaths domain(0, 0, DIM_W, DIM_H); float dx = (float) (domain.dx / (float) DIM_W); float dy = (float) (domain.dy / (float) DIM_H); float y = domain.y0; for(int i = 1; i <= DIM_W; ++i){ float x = domain.x0; for(int j = 1; j <= DIM_H; ++j){ float c = perlinNoise(x,y, 1); setFloatRGBA(image, i, j, 135, 206, 250, c * 255.0); x += dx; } y += dy; } }
float Simulation::getDisplacement(const Vec3f& pos, double timestep) const { float amplitude = 0.4 * (plates[0].getVelocity().Length() + plates[1].getVelocity().Length());//0.001; // If the overlap is empty, displace the vertices down, not up if (overlap.isEmpty()) amplitude *= -1; // If the overlap is too small, don't bother displacing yet if (fabs(overlap.getArea()) < 0.1 * timestep / 1000) return 0; Vec3f center = overlap.getMidpoint(pos); float spread = 0.5 * overlap.getWidth(); // Compute Gaussian function float y = amplitude * exp(-1 * (pos.x() - center.x()) * (pos.x() - center.x()) / (2 * spread * spread)); // Compute Perlin noise float noiseFactor = -0.3 * y * perlinNoise(randomFloat(0, 1), randomFloat(0, 1)); return y + noiseFactor; }
void bone::update(float preIncr) { { float incr = preIncr; float reduceVel = 1.0; //rotY -= 0.001; float inc_scale = 1.0; float post_scale = 6e4; rotXvel += 2.0*M_PI * (perlinNoise(inc_scale*incr) - 0.5)/post_scale; //rotX += rotXvel; rotYvel += 2.0*M_PI * (perlinNoise(inc_scale*incr+1e5) - 0.5)/post_scale; rotY += rotYvel; rotZvel += 2.0*M_PI * (perlinNoise(inc_scale*incr +2e5) - 0.5)/post_scale; rotZ += rotZvel; /// joint limits could be per bone, and somewhat random float limit = M_PI*0.25; if (rotX >= limit) { rotX = limit - M_PI/100.0; rotXvel = -rotXvel*reduceVel; } if (rotX <= 0) {rotX = 0 + M_PI/100.0; rotXvel = -rotXvel*reduceVel; } limit = M_PI*0.9; if (rotY >= limit) { rotY = limit - M_PI/100.0; rotYvel = -rotYvel*reduceVel; } if (rotY <= -limit) {rotY = -limit + M_PI/100.0; rotYvel = -rotYvel*reduceVel; } if (rotZ >= limit) { rotZ = limit - M_PI/100.0; rotZvel = -rotZvel*reduceVel; } if (rotZ <= -limit) {rotZ = -limit + M_PI/100.0; rotZvel = -rotZvel*reduceVel; } rotXvel *= 0.999; rotYvel *= 0.999; rotZvel *= 0.999; osg::Quat quat = osg::Quat( rotX, osg::Vec3(1,0,0), rotY, osg::Vec3(0,1,0), rotZ, osg::Vec3(0,0,1) ); att->setAttitude(quat); } if (parent == NULL) return; osg::Group* group = dynamic_cast<osg::Group*>(object); osg::Geode* geode = dynamic_cast<osg::Geode*>(group->getChild(0)); #ifdef VECS2 osg::Vec3Array* vecs2 = new osg::Vec3Array(*vecs, osg::CopyOp::DEEP_COPY_ALL); #endif bool doBones = true; if (doBones) { //osg::Matrixd rot(att->getAttitude() ); //osg::Matrixd rot2(objpos->getAttitude() ); //osg::Matrixd rot1 = objpos->getWorldMatrices()[0]; //osg::Vec3 cenDiff = rot2.preMult(osg::Vec3(0,0,0)) - rot1.preMult(osg::Vec3(0,0,0)); #ifdef VECS2 osg::Matrixd rot2 = objposNoAtt->getWorldMatrices()[0]; #endif /// do the position mixing for (unsigned i = 0; i < vecs->getNumElements() && parentWeights.size() ; i++) { osg::Vec3 pos = (*origVecs)[i]; //osg::Vec3d parentPos = rot.preMult( (*origVecs)[i] ); //parentPos = rot2.preMult( parentPos ); //osg::Vec3d newPos = parentPos*parentWeights[i] + (*origVecs)[i]*(1.0-parentWeights[i]); //(*vecs)[i] = newPos; //osg::Vec3d diff = rot2.preMult(pos) - rot1.preMult(pos); //(*vecs)[i] = pos;// + diff; //*parentWeights[i]; /// for some reason the rotations are mismatched for X & Z but not Y /// is there some rotation between att and root that doesn't matter for Y? /// it's the rotation put on by objpos osg::Quat slerped; slerped.slerp(parentWeights[i], att->getAttitude(), root->getAttitude()); osg::Vec3 slerpedPos = (slerped)*pos; (*vecs)[i] = slerpedPos; //(*vecs)[i] = pos; #ifdef VECS2 /// this is basically it, but there's a discontinuity /// problem with the rotation passing through PI/2 /// (*vecs2)[i] = rot2.preMult(slerpedPos); //(*vecs2)[i] = rot2.preMult(slerpedPos); #endif } } { osg::Group* group = dynamic_cast<osg::Group*>(object); osg::Geode* geode = dynamic_cast<osg::Geode*>(group->getChild(0)); if(!geode) { osg::notify(osg::WARN) << "failed to load mesh " << std::endl; return; } osg::Geometry* mesh = dynamic_cast<osg::Geometry*>(geode->getDrawable(0)); if(!mesh) { osg::notify(osg::WARN) << mesh << ": mesh " << " was expected to contain a single drawable" << std::endl; return; } mesh->setVertexArray(vecs); osgUtil::SmoothingVisitor sv; sv.smooth(*mesh); } /// temp to do same for object2 #ifdef VECS2 { osg::Group* group = dynamic_cast<osg::Group*>(object2); osg::Geode* geode = dynamic_cast<osg::Geode*>(group->getChild(0)); if(!geode) { osg::notify(osg::WARN) << "failed to load mesh " << std::endl; return; } osg::Geometry* mesh = dynamic_cast<osg::Geometry*>(geode->getDrawable(0)); if(!mesh) { osg::notify(osg::WARN) << mesh << ": mesh " << " was expected to contain a single drawable" << std::endl; return; } mesh->setVertexArray(vecs2); osgUtil::SmoothingVisitor sv; sv.smooth(*mesh); } #endif }