示例#1
0
/** Compute forces and update particles **/
void ParticleSystem::computeForcesAndUpdateParticles(float t)
{
	time = t;
	if (!simulate) return;

	for (int i = 0; i < 20; i++)
	{
		for (int j = 19; j >= 0; j--)
		{
			if (i == 0 && (j == 0 || j == 19)) continue;
			Vec3f force = Vec3f(g);
			Vec3f position = particles[i][j].getPosition();
			
			force += springForce(i - 1, j, position);
			force += springForce(i + 1, j, position);
			force += springForce(i, j - 1, position);
			force += springForce(i, j + 1, position);

			if (force.length() > 10)
			{
				force.normalize();
				force *= 10;
			}

			particles[i][j].applyForce(force);
		}
	}
	
	for (int i = 0; i < 20; i++)
		for (int j = 19; j >= 0; j--)
			particles[i][j].move(t);

	bakeParticles(t);
}
示例#2
0
/** Compute forces and update initial_state **/
void ParticleSystem::computeForcesAndUpdateParticles(float t)
{

	// TODO
	if (simulate){
		// no need to update if the particles are already baked
		float roundedTime = round(t*bake_fps) / bake_fps;
		if (bakedParticles.count(roundedTime)){
			return;
		}

		// compute new force

		for (int i = 0; i < n; i++){
			// clear force accumulator
			float newForVectors[3] = { 0.0, 0.0, 0.0 };
			particles[i].setPositionVectors(newForVectors);

			float* derivatives = new float[6 * n];
			float totalForce[3] = { 0.0, 0.0, 0.0 };
			// gravity force
			float gravityForce[3] = { 0.0, particles[i].getMass() * (-1) * 9.8, 0.0 };
			totalForce[0] += gravityForce[0];
			totalForce[1] += gravityForce[1];
			totalForce[2] += gravityForce[2];

			// air drag
			float airDragCoeff = 10;
			float airDrag[3] = { airDragCoeff*particles[i].getVelocityVectors()[0], airDragCoeff*particles[i].getVelocityVectors()[1], airDragCoeff*particles[i].getVelocityVectors()[2] };
			totalForce[0] += airDrag[0];
			totalForce[1] += airDrag[1];
			totalForce[2] += airDrag[2];

			//update particles derivatives
			derivatives[0] = particles[i].getVelocityVectors()[0];
			derivatives[1] = particles[i].getVelocityVectors()[1];
			derivatives[2] = particles[i].getVelocityVectors()[2];
			derivatives[3] = totalForce[0] / particles[i].getMass();
			derivatives[4] = totalForce[1] / particles[i].getMass();
			derivatives[5] = totalForce[2] / particles[i].getMass();

			float newPosVectors[3];
			float newVelVectors[3];
			newPosVectors[0] = particles[i].getPositionVectors()[0] + 1.0 / bake_fps*derivatives[0];
			newPosVectors[1] = particles[i].getPositionVectors()[1] + 1.0 / bake_fps*derivatives[1];
			newPosVectors[2] = particles[i].getPositionVectors()[2] + 1.0 / bake_fps*derivatives[2];
			newVelVectors[0] = particles[i].getVelocityVectors()[0] + 1.0 / bake_fps*derivatives[3];
			newVelVectors[1] = particles[i].getVelocityVectors()[1] + 1.0 / bake_fps*derivatives[4];
			newVelVectors[2] = particles[i].getVelocityVectors()[2] + 1.0 / bake_fps*derivatives[5];

			// reset the position of the particles if it exceeds the limit
			double limit = 5.0;
			if (newPosVectors[0] > limit || newPosVectors[1] > limit || newPosVectors[2] > limit){
				newPosVectors[0] = initial_state[i].getPositionVectors()[0];
				newPosVectors[1] = initial_state[i].getPositionVectors()[1];
				newPosVectors[2] = initial_state[i].getPositionVectors()[2];
				newVelVectors[0] = initial_state[i].getVelocityVectors()[0];
				newVelVectors[1] = initial_state[i].getVelocityVectors()[1];
				newVelVectors[2] = initial_state[i].getVelocityVectors()[2];
			}
			// update particles state
			particles[i].setPositionVectors(newPosVectors);
			particles[i].setVelocityVectors(newVelVectors);
			particles[i].setForceVectors(totalForce);

			delete[] derivatives;
		}
		

		bakeParticles(roundedTime);
	}

}