void GeometryCollisionParticleSystemAffector::affect(ParticleSystemRefPtr System, const Time& elps)
{
	UInt32 NumParticles(System->getNumParticles());
	
	Line ray;
    IntersectAction *iAct = IntersectAction::create();
	Pnt3f ParticlePos, ParticleSecPos;
    

	Real32 HitT(0.0f);
	for(UInt32 i(0) ; i<NumParticles ; ++i)
	{
		ParticlePos = System->getPosition(i);
		ParticleSecPos = System->getSecPosition(i);
		ray.setValue(ParticleSecPos, ParticlePos);
		iAct->setLine(ray);
		iAct->apply(getCollisionNode());
	    
		if (iAct->didHit())
		{
			HitT = iAct->getHitT();
			if(HitT > 0.0f && HitT*HitT<ParticlePos.dist2(ParticleSecPos))
			{
				produceParticleCollision(System, i, iAct);
                for(UInt32 j(0) ; j<getMFCollisionAffectors()->size(); ++j)
                {
                    getCollisionAffectors(i)->affect(System,i,elps);
                }
			}
		}
	}
}
Exemple #2
0
void CSheetSimulator::Init( int w, int h, int fixedPointCount )
{
	m_ControlPointOffset.Init( 0, 0, 0 );
	m_HorizontalCount = w;
	m_VerticalCount = h;
	m_Particle = new Particle_t[w * h];
	m_FixedPointCount = fixedPointCount;
	if (fixedPointCount)
	{
		m_pFixedPoint = new Vector[fixedPointCount];
		m_ControlPoints = new Vector[fixedPointCount];
		m_pCollisionPlanes = new cplane_t[fixedPointCount];
		m_pValidCollisionPlane = new bool[fixedPointCount];
	}

	// Initialize distances and such
	m_Origin = Vector(0, 0, 0);
	for ( int i = 0; i < NumParticles(); ++i )
	{
		m_Particle[i].m_Mass = 1.0f;
		m_Particle[i].m_Collided = false;
		m_Particle[i].m_Position = Vector(0,0,0);
		m_Particle[i].m_Velocity = Vector(0,0,0);
	}
}
Exemple #3
0
void Update(Scene* scene, float dt)
{
    Particle* particles = &scene->mParticles[0];
    Triangle* triangles = &scene->mTriangles[0];
    Element* elements = &scene->mElements[0];
    const Vec3* planes = &scene->mPlanes[0];

    uint32_t numParticles = NumParticles(scene);
    uint32_t numTriangles = NumTriangles(scene);
    uint32_t numPlanes = scene->mPlanes.size();

    SceneParams params = scene->mParams;

    FractureEvent* fractures = &scene->mFractures[0];
    uint32_t maxFractures = scene->mFractures.size();

    uint32_t numFractures = UpdateForces(particles, numParticles, triangles, elements, numTriangles,
                                         params.mGravity, params.mLameLambda, params.mLameMu, params.mDamping, params.mDrag, dt,
                                         fractures, maxFractures, params.mToughness, params.mYield, params.mCreep);

    CollidePlanes(particles, numParticles, planes, numPlanes, params.mFriction);

    IntegrateForces(particles, numParticles, dt);

    //if (numFractures)
    //	cout << "numFractures: " << numFractures << endl;

    // todo. ugh figure out a better way to manage this
    scene->mParticles.resize(2*numParticles);
    particles = &scene->mParticles[0];

    /*
    glColor3f(1.0f, 0.0f, 0.0f);
    glBegin(GL_LINES);
    for (size_t i=0; i < numFractures; ++i)
    {
    	Vec2 p = Vec2(fractures[i].mPlane)*-fractures[i].mPlane.z;
    	Vec2 n = PerpCCW(Vec2(fractures[i].mPlane));

    	glVertex2fv(p+n*100.0f);
    	glVertex2fv(p-n*100.0f);

    	glVertex2fv(p);
    	glVertex2fv(p + Vec2(fractures[i].mPlane));

    }
    glEnd();
    */

    if (params.mToughness > 0.0f)
    {
        numParticles = Fracture(particles, numParticles, triangles, numTriangles, fractures, numFractures);

        numParticles = SeparateSingular(particles, numParticles, triangles, numTriangles);
    }

    scene->mParticles.resize(numParticles);
    particles = &scene->mParticles[0];
}
Exemple #4
0
void CSheetSimulator::ClearForces()
{
	int i;
	for ( i = 0; i < NumParticles(); ++i)
	{
		m_Particle[i].m_Force = Vector(0,0,0);
	}
}
Exemple #5
0
void CSheetSimulator::ComputeBounds( Vector& mins, Vector& maxs )
{
	VectorCopy( m_Particle[0].m_Position, mins );
	VectorCopy( m_Particle[0].m_Position, maxs );

	for (int i = 1; i < NumParticles(); ++i)
	{
		VectorMin( mins, m_Particle[i].m_Position, mins );
		VectorMax( maxs, m_Particle[i].m_Position, maxs );
	}
	mins -= m_Origin;
	maxs -= m_Origin;
}
Exemple #6
0
void CSheetSimulator::SetPosition( const Vector& origin, const QAngle& angles )
{
	// FIXME: Need a better metric for position reset
	if (m_Origin.DistToSqr(origin) > 1e3)
	{
		for ( int i = 0; i < NumParticles(); ++i )
		{
			m_Particle[i].m_Position = origin;
			m_Particle[i].m_Velocity = Vector(0,0,0);
		}
	}

	m_Origin = origin;
	m_Angles = angles;
	ComputeControlPoints();
}
Exemple #7
0
void CSheetSimulator::SatisfyCollisionConstraints()
{
	// Eliminate velocity perp to a collision plane
	for ( int i = 0; i < NumParticles(); ++i )
	{
		// The actual collision plane 
		if (m_Particle[i].m_CollisionPlane >= 0)
		{
			cplane_t* pPlane = &m_pCollisionPlanes[m_Particle[i].m_CollisionPlane];

			// Fix up position so it lies on the plane
			Vector delta = m_Particle[i].m_Position - m_Origin;
			m_Particle[i].m_Position = m_Origin + delta * m_Particle[i].m_CollisionDist;

			float perp = DotProduct( m_Particle[i].m_Velocity, pPlane->normal );
			if (perp < 0)
				m_Particle[i].m_Velocity -=	pPlane->normal * perp;
		}
	}
}
Exemple #8
0
// Iterative collision detection 
void CIterativeSheetSimulator::DetectCollisions( void )
{
	for ( int i = 0; i < m_CollisionCount; ++i )
	{
		if (m_InitialPass)
		{
			InitPosition( m_CurrentCollisionPt );
		}
		else
		{
			float flOffset = COLLISION_PLANE_OFFSET * ( (float)(m_SimulationSteps - 1) / (float)(m_TotalSteps - 1) );
			DetectCollision( m_CurrentCollisionPt, flOffset );
		}

		if (++m_CurrentCollisionPt >= NumParticles())
		{
			m_CurrentCollisionPt = -1;
			m_InitialPass = false;
			break;
		}
	}
}
Exemple #9
0
void CSheetSimulator::ClampPointsToCollisionPlanes()
{
	// Find collision planes to clamp to
	DetermineBestCollisionPlane( false );

	// Eliminate velocity perp to a collision plane
	for ( int i = 0; i < NumParticles(); ++i )
	{
		// The actual collision plane 
		if (m_Particle[i].m_CollisionPlane >= 0)
		{
			cplane_t* pPlane = &m_pCollisionPlanes[m_Particle[i].m_CollisionPlane];

			// Make sure we have a close enough perpendicular distance to the plane...
			float flPerpDist = fabs ( DotProduct( m_Particle[i].m_Position, pPlane->normal ) - pPlane->dist );
			if (flPerpDist >= CLAMP_DIST)
				continue;

			// Drop it along the perp
			VectorMA( m_Particle[i].m_Position, -flPerpDist, pPlane->normal, m_Particle[i].m_Position );
		}
	}
}
Exemple #10
0
void CSheetSimulator::EulerStep( float dt )
{
	ClearForces();
	ComputeForces();

	// Update positions and velocities
	for ( int i = 0; i < NumParticles(); ++i)
	{
		m_Particle[i].m_Position += m_Particle[i].m_Velocity * dt; 
		m_Particle[i].m_Velocity += m_Particle[i].m_Force * dt / m_Particle[i].m_Mass;

		assert( _finite( m_Particle[i].m_Velocity.x ) &&
			_finite( m_Particle[i].m_Velocity.y) && 
			_finite( m_Particle[i].m_Velocity.z) );

		// clamp for stability
		float lensq = m_Particle[i].m_Velocity.LengthSqr();
		if (lensq > 1e6)
		{
			m_Particle[i].m_Velocity *= 1e3 / sqrt(lensq);
		}
	}
	SatisfyCollisionConstraints();
}
Exemple #11
0
void CSheetSimulator::ComputeForces()
{

	float springConstant;
	int i;
	for ( i = 0; i < m_Springs.Size(); ++i )
	{
		// Hook's law for a damped spring:
		// got two particles, a and b with positions xa and xb and velocities va and vb
		// and l = xa - xb
		// fa = -( ks * (|l| - r) + kd * (va - vb) dot (l) / |l|) * l/|l|

		Vector dx, dv, force;
		if (m_Springs[i].m_Particle2 < 0)
		{
			// Case where we're connected to a control point
			dx = m_Particle[m_Springs[i].m_Particle1].m_Position - 
				m_ControlPoints[- m_Springs[i].m_Particle2 - 1];
			dv = m_Particle[m_Springs[i].m_Particle1].m_Velocity;

			springConstant = m_FixedSpringConstant;
		}
		else
		{
			// Case where we're connected to another part of the shield
			dx = m_Particle[m_Springs[i].m_Particle1].m_Position - 
				m_Particle[m_Springs[i].m_Particle2].m_Position;
			dv = m_Particle[m_Springs[i].m_Particle1].m_Velocity - 
				m_Particle[m_Springs[i].m_Particle2].m_Velocity;

			springConstant = m_PointSpringConstant;
		}

		float length = dx.Length();
		if (length < 1e-6)
			continue;

		dx /= length;

		float springfactor = springConstant * ( length - m_Springs[i].m_RestLength);
		float dampfactor = m_DampConstant * DotProduct( dv, dx );
		force = dx * -( springfactor + dampfactor );

		m_Particle[m_Springs[i].m_Particle1].m_Force += force;
		if (m_Springs[i].m_Particle2 >= 0)
			m_Particle[m_Springs[i].m_Particle2].m_Force -= force;

		assert( _finite( m_Particle[m_Springs[i].m_Particle1].m_Force.x ) &&
			_finite( m_Particle[m_Springs[i].m_Particle1].m_Force.y) && 
			_finite( m_Particle[m_Springs[i].m_Particle1].m_Force.z) );
	}

	// gravity term
	for (i = 0; i < m_Gravity.Count(); ++i)
	{
		m_Particle[m_Gravity[i]].m_Force.z -= m_Particle[m_Gravity[i]].m_Mass * m_GravityConstant;
	}

	// viscous drag term
	for (i = 0; i < NumParticles(); ++i)
	{
		// Factor out bad forces for surface contact 
		// Do this before the drag term otherwise the drag will be too large
		if ((m_Particle[i].m_CollisionPlane) >= 0)
		{
			const Vector& planeNormal = m_pCollisionPlanes[m_Particle[i].m_CollisionPlane].normal;
			float perp = DotProduct( m_Particle[i].m_Force, planeNormal );
			if (perp < 0)
				m_Particle[i].m_Force -= planeNormal * perp;
		}

		Vector drag = m_Particle[i].m_Velocity * m_ViscousDrag;
		m_Particle[i].m_Force -= drag;
	}
}
Exemple #12
0
void GetParticles(const Scene* scene, Particle* dest)
{
    if (!scene->mParticles.empty())
        memcpy(dest, &scene->mParticles[0], sizeof(Particle)*NumParticles(scene));
}
Exemple #13
0
void SetParticles(Scene* scene, const Particle* src)
{
    scene->mParticles.assign(src, src+NumParticles(scene));
}
void ParticleInstancingRenderer::Render()
{

    glPushAttrib(GL_ALL_ATTRIB_BITS);
    CheckOpenGLError();

    const SphereGeometryVBO& level = *sphere_geometry_vbos[quality_level];

    glUseProgram(program_instancing);
    CheckOpenGLError();

    glValidateProgram(program_instancing);
    CheckOpenGLError();


    glUniform1i(glGetUniformLocation(program_instancing,"per_instance_data_position_radius"), 0);
    CheckOpenGLError();
    glUniform1i(glGetUniformLocation(program_instancing,"per_instance_data_attribute"), 1);
    CheckOpenGLError();


    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, level.GetVBOIndices());
    CheckOpenGLError();
    glBindBuffer(GL_ARRAY_BUFFER, level.GetVBOVertices());
    CheckOpenGLError();
    glVertexPointer(2, GL_FLOAT, 0, 0);
    CheckOpenGLError();

    glEnableClientState(GL_VERTEX_ARRAY);
    CheckOpenGLError();

    
    const size_t total_number_of_instances = NumParticles();
    const size_t number_of_batches = 1 + (total_number_of_instances - 1) / instanced_batch_size;

    for(size_t batch = 0, instances_remaining = total_number_of_instances; batch < number_of_batches; ++batch, instances_remaining -= instanced_batch_size)
    {
        size_t current_buffer = batch % 2;
        const size_t start_instance = batch * instanced_batch_size;
        const size_t instance_count = std::min(instances_remaining,instanced_batch_size);

        CopyParticleDataToGpuBuffers(start_instance,
                                     instance_count, 
                                     tbo_position_radius_batches[current_buffer],
                                     tex_position_radius_batches[current_buffer],
                                     tbo_color_batches[current_buffer], 
                                     tex_color_batches[current_buffer]);


        glActiveTexture(GL_TEXTURE0);
        CheckOpenGLError();
        glBindTexture(GL_TEXTURE_BUFFER_ARB, tex_position_radius_batches[current_buffer]);
        CheckOpenGLError();

        glActiveTexture(GL_TEXTURE1);
        CheckOpenGLError();
        glBindTexture(GL_TEXTURE_BUFFER_ARB, tex_color_batches[current_buffer]);
        CheckOpenGLError();

        glDrawElementsInstancedARB(GL_QUAD_STRIP, GLsizei(level.GetNumIndices()), GL_UNSIGNED_SHORT, 0, GLsizei(instance_count));
        CheckOpenGLError();

    }

    glDisableClientState(GL_VERTEX_ARRAY);
    CheckOpenGLError();

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    CheckOpenGLError();
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    CheckOpenGLError();

    glActiveTexture(GL_TEXTURE1);
    CheckOpenGLError();
    glBindTexture(GL_TEXTURE_BUFFER_ARB, 0);
    CheckOpenGLError();

    glActiveTexture(GL_TEXTURE0);
    CheckOpenGLError();	
    glBindTexture(GL_TEXTURE_BUFFER_ARB, 0);
    CheckOpenGLError();

    glUseProgram(0);
    CheckOpenGLError();

    glPopAttrib();
    CheckOpenGLError();
}
Action::ResultE LineParticleSystemDrawer::draw(DrawEnv *pEnv,
                                               ParticleSystemUnrecPtr System,
                                               const MFUInt32& Sort)
{
 	UInt32 NumParticles(System->getNumParticles());

	bool areEndpointsFadeSame(getEndPointFading().x() == getEndPointFading().y());
	Color4f Color;

	if(NumParticles != 0)
	{

		bool SeparateColors(System->getNumColors() > 1);
		bool SeparateSizes(System->getNumSizes() > 1);
		bool SeparateNormals(System->getNumNormals() > 1);

		glBegin(GL_LINES);
			//Colors
			if(!SeparateColors && areEndpointsFadeSame)
			{
				Color = System->getColor(0);
				glColor4f(Color.red(), Color.green(), Color.blue(), Color.alpha() * getEndPointFading().x());
			}
			//Sizes
			if(!SeparateSizes)
			{
				//glColor4fv(System->getColor(0).getValuesRGBA());
			}
			//Normals
			if(!SeparateNormals)
			{
				glNormal3fv(System->getNormal(0).getValues());
			}
			for(UInt32 i(0) ; i<NumParticles ; ++i)
			{
				//Start Color
				if(SeparateColors)
				{
					Color = System->getColor(i);
					glColor4f(Color.red(), Color.green(), Color.blue(), Color.alpha() * getEndPointFading().x());
				}
				else if(!SeparateColors && !areEndpointsFadeSame)
				{
					Color = System->getColor(0);
					glColor4f(Color.red(), Color.green(), Color.blue(), Color.alpha() * getEndPointFading().x());
				}
				//Sizes
				if(SeparateSizes)
				{
					//glColor4fv(System->getColor(i).getValuesRGBA());
				}
				//Normals
				if(SeparateNormals)
				{
					glNormal3fv(System->getNormal(i).getValues());
				}
				//Positions
				glVertex3fv(System->getPosition(i).getValues());
				
				//End Color
				if(SeparateColors && !areEndpointsFadeSame)
				{
					Color = System->getColor(i);
					glColor4f(Color.red(), Color.green(), Color.blue(), Color.alpha() * getEndPointFading().y());
				}
				else if(!SeparateColors && !areEndpointsFadeSame)
				{
					Color = System->getColor(0);
					glColor4f(Color.red(), Color.green(), Color.blue(), Color.alpha() * getEndPointFading().y());
				}
				glVertex3fv(getLineEndpoint(System, i).getValues());
			}
		glEnd();
	}

    return Action::Continue;
}