// Borrowed from http://community.wolfram.com/groups/-/m/t/176327 Vector3 CellularAutomata::normCoordToTorus(const Vector2& norm) { float r1 = 2.0f; float r2 = 1.0f; float theta = norm.x * 2.0f * pif(); float phi = norm.y * 2.0f * pif(); Point3 p( (r1 + r2*cos(phi))*cos(theta), -r2*sin(phi), (r1 + r2*cos(phi))*sin(theta)); return p; }
int main(int argc, char **argv) { if (argc != 2) { printf("usage: %s <module>\n", argv[0]); return EXIT_FAILURE; } int mod = atoi(argv[1]); PixieInterface pif("pixie.cfg"); pif.GetSlots(); pif.Init(); pif.Boot(PixieInterface::DownloadParameters | PixieInterface::ProgramFPGA | PixieInterface::SetDAC, true); OffsetAdjuster adjuster; if (forModule<int>(pif, mod, adjuster)) { pif.SaveDSPParameters(); } return EXIT_SUCCESS; }
void OBJWriterNodeVisitor::processGeometry(osg::Geometry* geo, osg::Matrix& m) { _fout << std::endl; _fout << "o " << getUniqueName( geo->getName().empty() ? geo->className() : geo->getName() ) << std::endl; if (geo->containsDeprecatedData()) geo->fixDeprecatedData(); processStateSet(_currentStateSet.get()); processArray("v", geo->getVertexArray(), m, false); processArray("vn", geo->getNormalArray(), m, true); processArray("vt", geo->getTexCoordArray(0)); // we support only tex-unit 0 unsigned int normalIndex = 0; for(unsigned int i = 0; i < geo->getNumPrimitiveSets(); ++i) { osg::PrimitiveSet* ps = geo->getPrimitiveSet(i); ObjPrimitiveIndexWriter pif(_fout, geo, normalIndex, _lastVertexIndex, _lastNormalIndex, _lastTexIndex); ps->accept(pif); if(geo->getNormalArray() && geo->getNormalArray()->getBinding() == osg::Array::BIND_PER_PRIMITIVE_SET) ++normalIndex; } if (geo->getVertexArray()) _lastVertexIndex += geo->getVertexArray()->getNumElements(); if (geo->getNormalArray()) _lastNormalIndex += geo->getNormalArray()->getNumElements(); if(geo->getTexCoordArray(0)) _lastTexIndex += geo->getTexCoordArray(0)->getNumElements(); }
int main(int argc, char *argv[]) { if (argc != 3) { printf("usage: %s <module> <channel>\n", argv[0]); exit(EXIT_FAILURE); } int mod = atoi(argv[1]); int ch = atoi(argv[2]); PixieInterface pif("pixie.cfg"); pif.GetSlots(); pif.Init(); pif.Boot(PixieInterface::DownloadParameters | PixieInterface::ProgramFPGA | PixieInterface::SetDAC, true); GoodToggler toggler; if (forChannel(pif, mod, ch, toggler)) pif.SaveDSPParameters(); return EXIT_SUCCESS; }
Color3 Raytracer::shadeDirectBSDF(const SurfaceSample& intersector, const Ray& ray) const { Color3 lightContribution(0,0,0); for (int i = 0; i < _currentScene->lighting()->lightArray.length(); ++i) { GLight& light = _currentScene->lighting()->lightArray[i]; const Point3& X = intersector.shadingLocation; const Point3& n = intersector.shadingNormal; const Vector3& diff = light.position.xyz() - X; const Vector3 w_i = diff.direction(); const float distance = diff.length(); const Vector3 w_eye = -ray.direction(); const Power3& Phi = light.color.rgb(); if (!isInSpotlight(light, w_i)) { continue; } if (isInShadow(intersector, w_i, distance)) { continue; } // power area const Color3& E_i = w_i.dot(n) * Phi / (4 * pif() * (distance*distance)); const SuperBSDF::Ref bsdf = intersector.material->bsdf(); const Color3& bsdfColor = bsdf->evaluate(intersector.shadingNormal, intersector.texCoord, w_i, w_eye).rgb(); lightContribution += bsdfColor * E_i + intersector.emit; } return lightContribution; }
void ParticleSystem::spawnSurface() { for (int i = 0; i < numParticles; ++i) { Particle& particle = m_particle.next(); PhysicsData& physicsData = m_physicsData.next(); Vector3 n; mesh.getRandomSurfacePoint(particle.position, n); particle.position = (transform * Vector4(particle.position, 1.0f)).xyz() + n * explode; particle.materialIndex = materialIndex; particle.color = c; particle.angle = rnd.uniform(0.0f, 2.0f) * pif(); particle.radius = radius; particle.emissive = 0; physicsData.angularVelocity = rnd.uniform(-1.0f, 1.0f) * (360.0f * units::degrees()) / (20.0f * units::seconds()); bounds.merge(particle.position); } // Center const Vector3 offset = -bounds.center(); for (int i = 0; i < m_particle.size(); ++i) { m_particle[i].position += offset; } m_lastObjectSpaceAABoxBounds = bounds + offset; }
void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix ( scalarField& result, const scalarField& psiInternal, const scalarField& coeffs, const direction cmpt, const Pstream::commsTypes ) const { const labelUList& nbrFaceCells = cyclicAMIPatch_.cyclicAMIPatch().neighbPatch().faceCells(); scalarField pnf(psiInternal, nbrFaceCells); // Transform according to the transformation tensors transformCoupleField(pnf, cmpt); if (cyclicAMIPatch_.applyLowWeightCorrection()) { scalarField pif(psiInternal, cyclicAMIPatch_.faceCells()); pnf = cyclicAMIPatch_.interpolate(pnf, pif); } else { pnf = cyclicAMIPatch_.interpolate(pnf); } // Multiply the field by coefficients and add into the result const labelUList& faceCells = cyclicAMIPatch_.faceCells(); forAll(faceCells, elemI) { result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI]; }
int main(int argc, char *argv[]) { HLIMIT(PAWC_SIZE); if (argc != 3) { printf("usage: %s <module> <channel>\n", argv[0]); exit(EXIT_FAILURE); } int mod = atoi(argv[1]); int ch = atoi(argv[2]); PixieInterface pif("pixie.cfg"); pif.GetSlots(); pif.Init(); usleep(200); pif.Boot(PixieInterface::DownloadParameters | PixieInterface::ProgramFPGA | PixieInterface::SetDAC, true); TraceGrabber grabber; forChannel(pif, mod, ch, grabber); char traceFile[] = "trace.dat"; char fileOptions[] = "N"; HRPUT (0, traceFile, fileOptions); return EXIT_SUCCESS; }
/* * Cerca prima di tutto nei titoli. * Successivamente, cerca l'accorrenza della parola *ricerca nei byte del file * compresi tra inizio e fine. */ void stampa_ricerca(Canzoniere *canzoniere, char *ricerca) { FILE *fpin; char riga[MAX_RIGA]; int i, j; printf("\nRisultati della ricerca nei titoli:\n"); for(i = 0; i < canzoniere->num_brani; i++) { if(pif(canzoniere->brani[i].titolo, ricerca)) { printf("%d) %s\n", i + 1, canzoniere->brani[i].titolo); } } fpin = fopen(canzoniere->filename, "r"); if(fpin == NULL) return; printf("\nRisultati della ricerca nelle canzoni:\n"); for(i = 0; i < canzoniere->num_brani; i++) { fseek(fpin, canzoniere->brani[i].inizio, SEEK_SET); /* Continua finché si può leggere e non abbiamo superato ancora il byte di fine */ while((fgets(riga, MAX_RIGA, fpin) != NULL) && (ftell(fpin) <= canzoniere->brani[i].fine)) { if(strstr(riga, ricerca) != NULL ) { printf("%d) %s\n", i + 1, canzoniere->brani[i].titolo); break; } } } fclose(fpin); }
void WriterNodeVisitor::createListTriangle(osg::Geometry * geo, ListTriangle & listTriangles, bool & texcoords, unsigned int & drawable_n) { const osg::Array * basevecs = geo->getVertexArray(); if (!basevecs || basevecs->getNumElements()==0) return; // Texture coords const osg::Array * basetexvecs = geo->getNumTexCoordArrays()>=1 ? geo->getTexCoordArray(0) : NULL; if (basetexvecs) { unsigned int nb = basetexvecs->getNumElements(); if (nb != geo->getVertexArray()->getNumElements()) { OSG_NOTIFY(osg::FATAL) << "There are more/less texture coords than vertices (corrupted geometry)" << std::endl; _succeeded = false; return; } texcoords = true; } int material = processStateSet(_currentStateSet.get()); for(unsigned int i = 0; i < geo->getNumPrimitiveSets(); ++i) //Fill the Triangle List { osg::PrimitiveSet* ps = geo->getPrimitiveSet(i); PrimitiveIndexWriter pif(geo, listTriangles, drawable_n, material); ps->accept(pif); } }
//static const Point3 MAX_POS(10, 5, 0); void PlayerEntity::onSimulation(GameTime absoluteTime, GameTime deltaTime) { // Do not call Entity::onSimulation; that will override with spline animation m_previousFrame = m_frame; simulatePose(absoluteTime, deltaTime); //m_velocity = m_frame.vectorToWorldSpace(m_desiredOSVelocity); //m_frame.translation += m_velocity * (float)deltaTime; if (!isNaN(deltaTime)) { slideMove(deltaTime); m_heading += m_desiredYawVelocity * (float)deltaTime; m_frame.rotation = Matrix3::fromAxisAngle(Vector3::unitY(), m_heading); m_headTilt = clamp(m_headTilt + m_desiredPitchVelocity, -pif()/2, pif()/2); } }
Color3 Surfel::probabilityOfScattering (PathDirection pathDirection, const Vector3& wi, Random& rng, const ExpressiveParameters& expressiveParameters) const { Color3 prob; // Sum the impulses (no cosine; principle of virtual images) ImpulseArray impulseArray; getImpulses(pathDirection, wi, impulseArray); for (int i = 0; i < impulseArray.size(); ++i) { prob += impulseArray[i].magnitude; } // This is uniform random sampling; would some kind of // striated or jittered sampling might produce a // lower-variance result. // Sample the finite portion. Note the implicit cosine // weighting in the importance sampling of the sphere. const int N = 32; if (transmissive()) { // Check the entire sphere // Measure of each sample on a cosine-weighted sphere // (the area of a cosine-weighted sphere is 2.0) const float dw = 2.0f * pif() / float(N); for (int i = 0; i < N; ++i) { const Vector3& wo = Vector3::cosSphereRandom(shadingNormal, rng); prob += finiteScatteringDensity(pathDirection, wi, wo, expressiveParameters) * dw; } } else { // Check only the positive hemisphere since the other hemisphere must be all zeros // Measure of each sample on a cosine-weighted hemisphere const float dw = 1.0f * pif() / float(N); for (int i = 0; i < N; ++i) { const Vector3& wo = Vector3::cosHemiRandom(shadingNormal, rng); prob += finiteScatteringDensity(pathDirection, wi, wo, expressiveParameters) * dw; } } return prob; }
void DXFWriterNodeVisitor::processGeometry(osg::Geometry* geo, osg::Matrix& m) { // We only want to create a new layer for geometry with something to draw if (geo->getVertexArray() && geo->getVertexArray()->getNumElements() ) { if ( _firstPass ) { // Must have unique layer names _layer._name = getLayerName( geo->getName().empty() ? geo->getParent(0)->getName() : geo->getName() ); OSG_DEBUG << "adding Layer " << _layer._name << std::endl; // if single colour include in header osg::Array::Binding colorBinding = osg::getBinding(geo->getColorArray()); if ( osg::Array::BIND_OVERALL == colorBinding ) { _layer._color = _acadColor.findColor(getNodeRGB(geo)); // per layer color } else if ( osg::Array::BIND_OFF== colorBinding ) { _layer._color = 0xff; // use white - or can we easily lookup in texture? } else { _layer._color = 0; // per point color } _layers.push_back(_layer); } else { _layer = _layers[_count++]; OSG_DEBUG << "writing Layer " << _layer._name << std::endl; processStateSet(_currentStateSet.get()); if ( geo->getNumPrimitiveSets() ) { for(unsigned int i = 0; i < geo->getNumPrimitiveSets(); ++i) { osg::PrimitiveSet* ps = geo->getPrimitiveSet(i); DxfPrimitiveIndexWriter pif(_fout, geo,_layer,_acadColor,m,_writeTriangleAs3DFace); ps->accept(pif); } } else { // Is array visitor necessary for only dealing with vertex arrays? //processArray(geo->getVertexArray(), _layer,m); if ( geo->getVertexArray() ) { osg::Vec3Array* data=static_cast<osg::Vec3Array*>(geo->getVertexArray()); for (unsigned int ii=0;ii<data->getNumElements();ii++) { osg::Vec3 point = data->at(ii) * m; _fout << "0 \nVERTEX\n 8\n"<<_layer._name<<"\n"; if ( _layer._color ) { _fout << "62\n"<<_layer._color<<"\n"; } else { _fout << "62\n"<<_acadColor.findColor(getNodeRGB(geo,ii))<<"\n"; } _fout<<" 10\n"<<point.x()<<"\n 20\n"<<point.y()<<"\n 30\n"<<point.z()<<"\n"; } } } } } }
Color3 Raytracer::myShadePixel(const Tri::Intersector& intersector, const Ray& ray, int backwardBouncesLeft) const { ray; backwardBouncesLeft; Vector3 position, normal; Vector2 texCoord; intersector.getResult(position, normal, texCoord); SurfaceSample surfaceSample(intersector); Color3 lightContribution(0,0,0); for (int i = 0; i < _currentScene->lighting()->lightArray.length(); ++i) { GLight& light = _currentScene->lighting()->lightArray[i]; const float lightDistance = light.distance(position); const Power3 power = light.power().rgb(); check(power.average()); const float lightArea = 4 * pif() * lightDistance * lightDistance; const Color3 kx = surfaceSample.lambertianReflect; const Vector3 light_in = (light.position.xyz() - position).unit(); const float lightIn_dot_normal = light_in.dot(normal); // Spotlight if (!isInSpotlight(light, light_in)) { continue; } if (isInShadow(surfaceSample, light_in, lightDistance)) { continue; } Color3 fx(0, 0, 0); if (lightIn_dot_normal > 0) { fx = kx / pif(); } lightContribution += (power / lightArea) * lightIn_dot_normal * fx; } return lightContribution; }
Color3 App::sampleLightArea( World* world,Random& rng,const Ray& ray, shared_ptr<Surfel> surfel){ Color3 e = Color3(0.0f,0.0f,0.0f); Sphere sp; //For each sphere light for (int L = 0 ; L < world->lightSurfacesIndex.size() ; L++ ) { world->getLightSpherei(L,sp); //Create coordinate system for sampling sw, su, sv Vector3 sw = sp.center - surfel->position; // vector in the direction of the light center // (sw.y > 1 - eps) is equivalent to (sw.x^2 + sw.z^2) = ||sw \cross (0,1,0)||^2 < 0.1 Vector3 su = sw.cross((abs(sw.y) > 0.9) ? Vector3(1,0,0) : Vector3(0,1,0)); su = su.unit(); Vector3 sv = sw.cross(su); // Determine max angle float cos_a_max = sqrt(1.0 - sp.radius*sp.radius/sw.dot(sw)); // Calculate sample direction (to light) based acording to equation from Realistic Rendering float eps1 = rng.uniform(); float eps2 = rng.uniform(); float cos_a = 1.0 - eps1 + (eps1*cos_a_max); float sin_a = sqrt(1.0 - cos_a*cos_a); float phi = 2.0*pif()*eps2; float xx = cos(phi)*sin_a; float yy = sin(phi)*sin_a; float zz = cos_a; Vector3 ld = Vector3(xx*su.x + yy*sv.x + zz*sw.x, xx*su.y + yy*sv.y + zz*sw.y, xx*su.z + yy*sv.z + zz*sw.z); ld = ld.unit(); // Check for oclussion with shadow ray float dist = std::numeric_limits<float>::max(); Vector3 nl = surfel->shadingNormal.dot(ray.direction()) < 0 ? surfel->shadingNormal : surfel->shadingNormal*-1; const shared_ptr<Surfel>& lightSurfel = world->intersect(Ray(surfel->position+nl*BUMP_DISTANCE,ld), dist); if ( notNull(lightSurfel) && lightSurfel->emittedRadiance(ld).max() > 0.0) { float omega = 2.0*pif()*(1.0 - cos_a_max); e += (surfel->reflectivity(rng)*(m_world->getEmissiveFromLighti(L)*ld.dot(nl)*omega))*(1.0/pif()); } } return e; }
int main(int argc, char **argv) { Display::SetColorTerm(); PixieInterface pif("test.cfg"); pif.GetSlots(); pif.Init(); sleep(20); return EXIT_SUCCESS; }
tmp<Field<Type> > mixedFixedValueSlipFvPatchField<Type>::snGrad() const { tmp<vectorField> nHat = this->patch().nf(); Field<Type> pif(this->patchInternalField()); return ( valueFraction_*refValue_ + (1.0 - valueFraction_)*transform(I - sqr(nHat), pif) - pif )*this->patch().deltaCoeffs(); }
void ParticleSystem::setFogModel(const Color4& color, int materialIndex) { const Color4unorm8 c(Color4(color.r, color.g, color.b, pow(color.a, 1.0f / SmokeVolumeSet::PARTICLE_GAMMA))); Random rnd; Noise noise; m_particle.resize(5000); m_physicsData.resize(m_particle.size()); for (int i = 0; i < m_particle.size(); ++i) { SmokeVolumeSet::Particle& particle = m_particle[i]; PhysicsData& physicsData = m_physicsData[i]; // Fill sponza particle.position = Point3(rnd.uniform(-16, 14), pow(rnd.uniform(0, 1), 4.0f) * 4 + 0.5f, rnd.uniform(-6.5, 6.5)); /* if (rnd.uniform() < 0.3f) { // Arena bridge particle.position = Point3(rnd.uniform(-14, 14) - 2.0f, pow(rnd.uniform(0, 1), 5.0f) * 16.0f + 7.2f, rnd.uniform(-8, 8) - 28.0f); } else { // Arena everywhere particle.position = Point3(rnd.uniform(-20, 20), pow(rnd.uniform(0, 1), 5.0f) * 12.0f + 7.2f, rnd.uniform(-20, 20)); } */ particle.angle = rnd.uniform(0.0f, 2.0f) * pif(); particle.materialIndex = materialIndex; particle.radius = 1.0f; particle.emissive = 0.0f; particle.color = c; int r = rnd.integer(0, 15); particle.color.r = unorm8::fromBits(r + particle.color.r.bits()); particle.color.g = unorm8::fromBits(r + particle.color.g.bits()); particle.color.b = unorm8::fromBits(r + particle.color.b.bits()); physicsData.angularVelocity = 0;//rnd.uniform(-1.0f, 1.0f) * (360.0f * units::degrees()) / (5.0f * units::seconds()); // Unique values every 5m for the lowest frequencies const Vector3int32 intPos(particle.position * ((1 << 16) / (5 * units::meters()))); const float acceptProbability = pow(max(0.0f, noise.sampleFloat(intPos.x, intPos.y, intPos.z, 5)), 2.0f); if (rnd.uniform() > acceptProbability) { // Reject this puff --i; } } // Ensure that this matches m_physicsData.resize(m_particle.size()); }
float App::generateSample(Vector3& normal,Random& rng, Vector3& wDirection){ // x,y,z coordinates of the sample in the sphere float r1 = 2.0*pif()*rng.uniform(); float r2 = sqrt(rng.uniform()); float sampleX, sampleY, sampleZ; sampleX = cos(r1)*sqrt(1.0 - r2); sampleY = sin(r1)*sqrt(1.0 - r2); sampleZ = r2; Vector3 w = normal; // (w.y > 1 - eps) is equivalent to (w.x^2 + w.z^2) = ||w \cross (0,1,0)||^2 < 0.1 Vector3 u = w.cross((abs(w.y) > 0.9) ? Vector3(1,0,0) : Vector3(0,1,0)); u = u.unit(); Vector3 v = w.cross(u); wDirection = Vector3(sampleX*u.x + sampleY*v.x + sampleZ*w.x, sampleX*u.y + sampleY*v.y + sampleZ*w.y, sampleX*u.z + sampleY*v.z + sampleZ*w.z); wDirection = wDirection.unit(); //For convinience this pdf is actually cos(theta)/PI*pdf (to just multiply it by the diffuse color of the object) return 1.0; // real pdf: 1 / 4PI }
int main(int argc, char *argv[]) { if (argc != 3) { printf("usage: %s <module> <channel>\n", argv[0]); exit(EXIT_FAILURE); } int mod = atoi(argv[1]); int ch = atoi(argv[2]); PixieInterface pif("pixie.cfg"); pif.GetSlots(); pif.Init(); pif.Boot(0, true); printf(" %2s %2s %10s %10s %10s %10s %10s\n", "M", "C", "Input", "Output", "Live_t", "Proc_ev", "RealTime"); StatsReader reader; forChannel(pif, mod, ch, reader); return EXIT_SUCCESS; }
static void directive() { Tok *t; char *dir; t = ppnoexpand(); dir = t->v; if(strcmp(dir, "include") == 0) include(); else if(strcmp(dir, "define") == 0) define(); else if(strcmp(dir, "if") == 0) pif(); else if(strcmp(dir, "elseif") == 0) elseif(); else if(strcmp(dir, "else") == 0) pelse(); else if(strcmp(dir, "endif") == 0) endif(); else errorposf(&t->pos, "invalid directive %s", dir); }
int main(int argc, char *argv[]) { if(argc < 5){ std::cout << " Invalid number of arguments to " << argv[0] << std::endl; std::cout << " SYNTAX: " << argv[0] << " [module] [channel] [parameter] [value]\n\n"; return 1; } int mod = atoi(argv[1]); int ch = atoi(argv[2]); double value = std::strtod(argv[4], NULL); PixieInterface pif("pixie.cfg"); pif.GetSlots(); pif.Init(); pif.Boot(PixieInterface::DownloadParameters | PixieInterface::ProgramFPGA | PixieInterface::SetDAC, true); std::string temp_str(argv[3]); ParameterChannelWriter writer; if(forChannel(&pif, mod, ch, writer, make_pair(temp_str, value))){ pif.SaveDSPParameters(); } return 0; }
static float clampedConeVolume(float r) { return (square(clampedConeHeight) - 3.0f * clampedConeHeight + 3.0f) * (clampedConeHeight * pif() * square(r)) / 3.0f; }
Radiance3 Raytracer::shadeIndirectIllumination(const SurfaceSample& intersector) const { if (_settings._debugPixelTrace) { int suresh = 1374; } Radiance3 accumulatedPhotonRadiance; const Point3& X = intersector.shadingLocation; const Point3& n = intersector.shadingNormal; const float radius = _settings._photonGatherRadius; const SuperBSDF::Ref bsdf = intersector.material->bsdf(); static bool increaseGathering = true; if (increaseGathering) { const int gatheredPhotons = 5000; int numberOfPhotons = 0; float increasingRadius = 0.0f; static float increasingRate = 0.05f; while (numberOfPhotons < gatheredPhotons && increasingRadius < radius) { // Gather all photons within radius of intersection const Sphere sphere(X, increasingRadius); PhotonGrid::SphereIterator it = _photonMap->beginSphereIntersection(sphere); while (it.hasMore()) { numberOfPhotons++; ++it; } increasingRadius += increasingRate; } const Sphere sphere(X, increasingRadius); PhotonGrid::SphereIterator it = _photonMap->beginSphereIntersection(sphere); //printf("%4.2f\n", increasingRadius); while (it.hasMore()) { const Vector3& diff = it->position.xyz() - X; const Vector3 w_i = diff.direction(); const Vector3 w_eye = -(it->direction); const Color3& bsdfColor = bsdf->evaluate(intersector.shadingNormal, intersector.texCoord, w_i, w_eye).rgb(); Radiance3 photo_illum = (it->power / ((pif() * increasingRadius*increasingRadius)/3)) * k((it->position - X).magnitude(), increasingRadius); photo_illum = photo_illum * max(0.0f, (it->direction * -1).dot(n)); photo_illum = photo_illum * bsdfColor; accumulatedPhotonRadiance += photo_illum; ++it; } } else { // Gather all photons within radius of intersection const Sphere sphere(X, radius); PhotonGrid::SphereIterator it = _photonMap->beginSphereIntersection(sphere); while (it.hasMore()) { const Vector3& diff = it->position.xyz() - X; const Vector3 w_i = diff.direction(); const Vector3 w_eye = -(it->direction); const Color3& bsdfColor = bsdf->evaluate(intersector.shadingNormal, intersector.texCoord, w_i, w_eye).rgb(); Radiance3 photo_illum = (it->power / ((pif() * radius*radius)/3)) * k((it->position - X).magnitude(), radius); photo_illum = photo_illum * max(0.0f, (it->direction * -1).dot(n)); photo_illum = photo_illum * bsdfColor; accumulatedPhotonRadiance += photo_illum; ++it; } } // Sum their power return accumulatedPhotonRadiance; }
float Cone::halfAngleFromSolidAngle(float solidAngle){ return acos((1.0f - (solidAngle / (2.0f * pif())))); }
Matrix3 CompassDirection::toHeadingMatrix3() const { return Matrix3::fromAxisAngle(Vector3::unitY(), zxRadians() + pif()); }
float Cone::solidAngleFromHalfAngle(float halfAngle){ return 2.0f * pif() * (1 - cosf(halfAngle)); }
void ParticleSystem::spawnFace (const FaceScatter& faceScatter, const ParseOBJ& parseObj, const Color4& color, const Matrix4& transform, int materialIndex) { const Color4unorm8 c(color.pow(1.0f / SmokeVolumeSet::PARTICLE_GAMMA)); Random rnd(10000, false); m_particle.resize(0); m_physicsData.resize(0); AABox bounds; for (ParseOBJ::GroupTable::Iterator git = parseObj.groupTable.begin(); git.isValid(); ++git) { const shared_ptr<ParseOBJ::Group>& group = git->value; for (ParseOBJ::MeshTable::Iterator mit = group->meshTable.begin(); mit.isValid(); ++mit) { const shared_ptr<ParseOBJ::Mesh>& mesh = mit->value; for (int f = 0; f < mesh->faceArray.size(); ++f) { if (rnd.uniform() <= faceScatter.particlesPerFace) { const ParseOBJ::Face& face = mesh->faceArray[f]; Particle& particle = m_particle.next(); PhysicsData& physicsData = m_physicsData.next(); // Use the average vertex as the position Point3 vrt[10]; particle.position = Point3::zero(); for (int v = 0; v < face.size(); ++v) { vrt[v] = (transform * Vector4(parseObj.vertexArray[face[v].vertex], 1.0f)).xyz(); particle.position += vrt[v]; } particle.position /= float(face.size()); const Vector3& normal = (vrt[1] - vrt[0]).cross(vrt[2] - vrt[0]).direction(); particle.position += faceScatter.explodeDistance * normal; particle.normal = normal; particle.materialIndex = materialIndex; particle.color = c; particle.angle = rnd.uniform(0.0f, 2.0f) * pif(); particle.radius = min(faceScatter.maxRadius, faceScatter.radiusScaleFactor * pow((particle.position - vrt[0]).length(), faceScatter.radiusExponent)); particle.emissive = 0; physicsData.angularVelocity = rnd.uniform(-1.0f, 1.0f) * (360.0f * units::degrees()) / (20.0f * units::seconds()); bounds.merge(particle.position); } } // face } // mesh } // group // Center if (faceScatter.moveCenterToOrigin) { const Vector3& offset = -bounds.center(); for (int i = 0; i < m_particle.size(); ++i) { m_particle[i].position += offset; } m_lastObjectSpaceAABoxBounds = bounds + offset; } else { m_lastObjectSpaceAABoxBounds = bounds; } }
void ParticleSystemModel::Emitter::spawnParticles(ParticleSystem* system, int newParticlesToEmit, SimTime absoluteTime, SimTime relativeTime, SimTime deltaTime, int emitterIndex) const { // Give up and just place a particle anywhere in the noise field if we can't find // a good location by rejection sampling after this many tries. const int MAX_NOISE_SAMPLING_TRIES = 20; Random& rng = Random::common(); Noise& noise = Noise::common(); debugAssert(notNull(m_spawnShape)); for (int i = 0; i < newParticlesToEmit; ++i) { ParticleSystem::Particle particle; particle.emitterIndex = emitterIndex; for (int j = 0; j < MAX_NOISE_SAMPLING_TRIES; ++j) { switch (m_specification.location) { case SpawnLocation::FACES: alwaysAssertM(m_spawnShape->type() == Shape::Type::MESH, "SpawnLocation::FACES requires a mesh"); { const shared_ptr<MeshShape>& mesh = dynamic_pointer_cast<MeshShape>(m_spawnShape); const Array<int>& indexArray = mesh->indexArray(); const Array<Point3>& vertexArray = mesh->vertexArray(); const int i = rng.integer(0, indexArray.size() / 3 - 1) * 3; particle.position = (vertexArray[indexArray[i]] + vertexArray[indexArray[i + 1]] + vertexArray[indexArray[i + 2]]) / 3.0f; } break; case SpawnLocation::VERTICES: alwaysAssertM(m_spawnShape->type() == Shape::Type::MESH, "SpawnLocation::VERTICES requires a mesh"); { const shared_ptr<MeshShape>& mesh = dynamic_pointer_cast<MeshShape>(m_spawnShape); particle.position = mesh->vertexArray().randomElement(); } break; case SpawnLocation::SURFACE: m_spawnShape->getRandomSurfacePoint(particle.position); break; case SpawnLocation::VOLUME: particle.position = m_spawnShape->randomInteriorPoint(); if (particle.position.isNaN()) { // For poorly formed meshes...or even good ones with really bad luck... // sometimes randomInteriorPoint will fail. In this case, generate a surface // point, which is technically "on the interior" still, just poorly distributed. m_spawnShape->getRandomSurfacePoint(particle.position); } break; } // switch // Unique values every 5m for the lowest frequencies if (m_specification.noisePower == 0.0f) { // Accept any generated position break; } else { const Vector3int32 intPos(particle.position * ((1 << 16) / (5 * units::meters()))); const float acceptProbability = pow(max(0.0f, noise.sampleFloat(intPos.x, intPos.y, intPos.z, 5)), m_specification.noisePower); if (rng.uniform() <= acceptProbability) { // An acceptable position! break; } } } particle.angle = rng.uniform(0.0f, 2.0f * pif()); particle.radius = fabs(rng.gaussian(m_specification.radiusMean, sqrt(m_specification.radiusVariance))); if (m_specification.coverageFadeInTime == 0.0f) { particle.coverage = 1.0f; } else { particle.coverage = 0.0f; } particle.userdataFloat = 0.0f; particle.mass = m_specification.particleMassDensity * (4.0f / 3.0f) * pif() * particle.radius * particle.radius * particle.radius; if (m_specification.velocityConeAngleDegrees >= 180) { particle.velocity = Vector3::random(rng); } else if (m_specification.velocityConeAngleDegrees > 0) { const Cone emissionCone(Point3(), m_specification.velocityDirectionMean, m_specification.velocityConeAngleDegrees * 0.5f); particle.velocity = emissionCone.randomDirectionInCone(rng); } else { particle.velocity = m_specification.velocityDirectionMean; } particle.velocity *= fabs(rng.gaussian(m_specification.velocityMagnitudeMean, m_specification.velocityMagnitudeVariance)); particle.angularVelocity = rng.gaussian(m_specification.angularVelocityMean, m_specification.angularVelocityVariance); particle.spawnTime = absoluteTime; particle.expireTime = absoluteTime + fabs(rng.gaussian(m_specification.particleLifetimeMean, m_specification.particleLifetimeVariance)); particle.dragCoefficient = m_specification.dragCoefficient; particle.material = m_material; particle.userdataInt = 0; if (system->particlesAreInWorldSpace()) { // Transform to world space particle.position = system->frame().pointToWorldSpace(particle.position); particle.velocity = system->frame().vectorToWorldSpace(particle.velocity); } // Directly add to the particle system system->m_particle.append(particle); } // for new particles if (newParticlesToEmit > 0) { system->markChanged(); } }
void onDraw(SkCanvas* canvas) override{ SkPaint blackFill; //----------- // Normal paints (no source) SkTArray<SkPaint> paints; create_paints(nullptr, &paints); //----------- // Paints with a PictureImageFilter as a source SkAutoTUnref<SkPicture> pic; { SkPictureRecorder rec; SkCanvas* c = rec.beginRecording(10, 10); c->drawRect(SkRect::MakeWH(10, 10), blackFill); pic.reset(rec.endRecording()); } SkAutoTUnref<SkPictureImageFilter> pif(SkPictureImageFilter::Create(pic)); SkTArray<SkPaint> pifPaints; create_paints(pif, &pifPaints); //----------- // Paints with a BitmapSource as a source SkBitmap bm; { SkPaint p; bm.allocN32Pixels(10, 10); SkCanvas temp(bm); temp.clear(SK_ColorYELLOW); p.setColor(SK_ColorBLUE); temp.drawRect(SkRect::MakeLTRB(5, 5, 10, 10), p); p.setColor(SK_ColorGREEN); temp.drawRect(SkRect::MakeLTRB(5, 0, 10, 5), p); } SkAutoTUnref<SkBitmapSource> bms(SkBitmapSource::Create(bm)); SkTArray<SkPaint> bmsPaints; create_paints(bms, &bmsPaints); //----------- SkASSERT(paints.count() == kNumVertTiles); SkASSERT(paints.count() == pifPaints.count()); SkASSERT(paints.count() == bmsPaints.count()); // horizontal separators for (int i = 1; i < paints.count(); ++i) { canvas->drawLine(0, i*SkIntToScalar(kTileHeight), SkIntToScalar((SK_ARRAY_COUNT(gDrawMthds) + kNumXtraCols)*kTileWidth), i*SkIntToScalar(kTileHeight), blackFill); } // vertical separators for (int i = 0; i < (int)SK_ARRAY_COUNT(gDrawMthds) + kNumXtraCols; ++i) { canvas->drawLine(SkIntToScalar(i * kTileWidth), 0, SkIntToScalar(i * kTileWidth), SkIntToScalar(paints.count() * kTileWidth), blackFill); } // A column of saveLayers with PictureImageFilters for (int i = 0; i < pifPaints.count(); ++i) { draw_savelayer_with_paint(SkIPoint::Make(0, i*kTileHeight), canvas, pifPaints[i]); } // A column of saveLayers with BitmapSources for (int i = 0; i < pifPaints.count(); ++i) { draw_savelayer_with_paint(SkIPoint::Make(kTileWidth, i*kTileHeight), canvas, bmsPaints[i]); } // Multiple columns with different geometry for (int i = 0; i < (int)SK_ARRAY_COUNT(gDrawMthds); ++i) { for (int j = 0; j < paints.count(); ++j) { draw_geom_with_paint(*gDrawMthds[i], SkIPoint::Make((i+kNumXtraCols) * kTileWidth, j*kTileHeight), canvas, paints[j]); } } }