Example #1
0
int main( int argc, char** argv ) {
	double		min[2]		= { -M_PI, -M_PI };
	double		max[2]		= { +M_PI, +M_PI };
	bool		periodic[2]	= { false, false };
	int		nx[2]		= { 8, 8 };
	Mesh*		mesh		= new Mesh( "mesh", nx, "legendre", 8, min, max, periodic );
	Field*		field		= new Field( "field", mesh, 1, NULL );
	Transform*	trans		= new Transform( field );

	mesh->Save();
	trans->fMesh->Save();

	field->SetICFunc( 0, r0 );
	WriteXDMFHeader( 0 );
	WriteXDMF( &field, 1, 0, 0.0, 0.0 );
	WriteXDMFFooter( 0 );

	trans->Interp();
	WriteXDMFHeader( 1 );
	WriteXDMF( &trans->fField, 1, 1, 0.0, 0.0 );
	WriteXDMFFooter( 1 );

	field->SetICFunc( 0, r1 );
	WriteXDMFHeader( 2 );
	WriteXDMF( &field, 1, 2, 0.0, 0.0 );
	WriteXDMFFooter( 2 );

	trans->Interp();
	WriteXDMFHeader( 3 );
	WriteXDMF( &trans->fField, 1, 3, 0.0, 0.0 );
	WriteXDMFFooter( 3 );

	trans->Forward();
	WriteXDMFHeader( 4 );
	WriteXDMF( &trans->fField, 1, 4, 0.0, 0.0 );
	WriteXDMFFooter( 4 );

	Filter( trans->fField );

	trans->Backward();
	WriteXDMFHeader( 5 );
	WriteXDMF( &field, 1, 5, 0.0, 0.0 );
	WriteXDMFFooter( 5 );

	delete mesh;
	delete field;
	delete trans;

	return 1;
}
Example #2
0
	Pollen() noexcept
		: type((Type)Random<uint32_t>(0u,3u))
	{
		{
			Lock lock(mxCounter);
			if ((++counter) == 1)
			{			
				//create an icosphere of radius 1.0f
				std::vector<Vec3> spherePositions;
				{
					Mesh mesh;
					auto data(mesh.Sphere({}, 1.0f, YGG_DEBUG_CONDITIONAL(2,4), true).Decompose());
					for (auto i : data->Indices)
						spherePositions.push_back(data->Positions[i]);
				}

				//deform a copy of the sphere once for each type
				for (Type t = Type::Linear; t < Type::Count; t = (Type)((uint32_t)t + 1u))
				{
					uint32_t spikeCount(40);
					switch (t)
					{
						case Type::Linear: spikeCount = 3 * spikeCount / 4; break;
						case Type::Square: spikeCount = 2 * spikeCount / 3; break;
						case Type::Circular: spikeCount = spikeCount / 2; break;
					}

					//pick equidistant points around unit sphere (see http://www.cmu.edu/biolphys/deserno/pdf/sphere_equi.pdf)
					std::vector<Vec3> spikes;
					float a((4.0f * Pi) / (float)spikeCount);
					float d(sqrtf(a));
					uint32_t mTheta(Round<uint32_t>(Pi / d));
					float dTheta(Pi / (float)mTheta);
					float dAlpha(a / dTheta);
					for (uint32_t m = 0; m < mTheta; ++m)
					{
						float theta((Pi*((float)m + 0.5f)) / (float)mTheta);
						uint32_t mAlpha(Round<uint32_t>((2.0f * Pi * sinf(theta)) / dAlpha));
						for (uint32_t n = 0; n < mAlpha; ++n)
						{
							float alpha((2.0f * Pi * (float)n) / (float)mAlpha);
							spikes.emplace_back(sinf(theta) * cosf(alpha),
								sinf(theta)*sinf(alpha),
								cos(theta));
						}
					}

					//minimum distance to consider a spike as being "in range"
					float rad = d / 2.1f;

					//loop through the vertices and deform the sphere based 
					//on proximity to nearest spike
					std::vector<Vec3> positions(spherePositions);
					for (size_t v = 0; v < positions.size(); ++v)
					{
						//find closest spike
						float dist(Vec3::DistanceSquared(positions[v], spikes[0]));
						for (size_t s = 1; s < spikes.size(); ++s)
							dist = std::min(dist, Vec3::DistanceSquared(positions[v], spikes[s]));

						//convert distance into a proximity function & deform
						dist = ((rad - sqrtf(dist)) / rad);
						positions[v] *= metrics.Radius + metrics.Radius * 0.25f * ApplyDeformation(t, dist);

					}

					//create static mesh
					Mesh mesh;
					meshes.emplace_back(new StaticMesh(mesh.AddPositions(std::move(positions)).GenerateIndices().GenerateNormals()));
				}

			}
			if (Game::Physics()->Started() && !rigidBodyMesh)
				rigidBodyMesh = Game::Physics()->CreateSphereMesh(metrics.Radius);
		}


		entity.reset(Game::Scene()->Create("", this));
		auto _position(PickSpawnLocation(true));
		transform = entity->Add<Transform>(_position);
		transform->Forward(Random<Vec3>());
		static std::vector<Colour> colours
		{
			Yellow, Olive, BlanchedAlmond, YellowGreen
		};
		material.reset(new Phong(Colour(colours[Random<size_t>(0, colours.size() - 1)],0.0f)));
		entity->Add<MeshRenderer>(meshes[Random<size_t>(0, meshes.size() - 1)], material);

		if (Game::Physics()->Started())
			rigidBody.reset(Game::Physics()->Create(rigidBodyMesh, true, _position, transform->Orientation(), metrics.Density));
		entity->Add<Ticker>()->OnTick += [](Ticker* t, float deltaTime)
		{
			auto pollen(static_cast<Pollen*>(t->Entity()->Data));
			if (Game::Physics()->Started())
				pollen->transform->Pose(pollen->rigidBody->Position(), pollen->rigidBody->Orientation());

			if (!world.Contains(pollen->transform->Position()))
			{
				Vec3 newPos(PickSpawnLocation(false));
				pollen->transform->Position(newPos);
				if (Game::Physics()->Started())
					pollen->rigidBody->Position(newPos).Stop();
				pollen->spawnTime = 0.0f;
			}

			pollen->spawnTime += deltaTime;
			float alpha(std::min(pollen->spawnTime * 0.33f,1.0f));
			if (!spawnBounds.Contains(pollen->transform->Position()))
			{
				alpha = std::min(1.0f - Clamp((Vec3::Distance(spawnBounds.Center, pollen->transform->Position()) - spawnBounds.Radius)
					/ (world.Radius - spawnBounds.Radius), 0.0f, 1.0f), alpha);
			}
			pollen->material->Colour(Colour(pollen->material->Colour(), alpha));
		};
	}