示例#1
0
void JelloMesh::ComputeForces(ParticleGrid& grid)
{
    // Add external froces to all points
    for (int i = 0; i < m_rows+1; i++)
    {
        for (int j = 0; j < m_cols+1; j++)
        {
            for (int k = 0; k < m_stacks+1; k++)
            {
                Particle& p = GetParticle(grid, i,j,k);
                p.force = m_externalForces * p.mass;
            }
        }
    }

    // Update springs
    for(unsigned int i = 0; i < m_vsprings.size(); i++)
    {
        Spring& spring = m_vsprings[i];
        Particle& a = GetParticle(grid, spring.m_p1);
        Particle& b = GetParticle(grid, spring.m_p2);

        // TODO
		vec3 xab = a.position - b.position;
		vec3 vab = a.velocity - b.velocity;
		vec3 force_change = - spring.m_Ks*(sqrt(xab*xab)-spring.m_restLen)*xab/(sqrt(xab*xab)) - spring.m_Kd*(vab*xab)*xab/(xab*xab);
		a.force += force_change;
		b.force -= force_change;
    }
}
示例#2
0
int SpringSystem::CreateSpring(int particleId1, int particleId2)
{
  Spring* spr = GetSpring(particleId1, particleId2);
  if (spr)
  {
    std::cout << "CreateSpring: found duplicate spring.\n";
    return spr->GetId();
  }

  int n = m_springs.size();
  spr = new Spring(n, GetParticle(particleId1), GetParticle(particleId2));
  m_springs.push_back(spr);

  // Add this spring to the map of springs connected to each particle
  m_springMap[particleId1].insert(spr);
  m_springMap[particleId2].insert(spr);

  // We have just set the natural length of the spring.
  // Set the min and max lengths based on this.
  // TODO This is a property of the squishy thing
  float natLen = spr->GetNaturalLength();
  // TODO TEMP TEST
  spr->SetMaxLength(natLen * 1.5f);
  spr->SetMinLength(natLen * 0.7f);
  return n;
}
void Physics_Cloth::CreateHooks()
{
	// Move the particles closer together make it look more like a curtain
	for (int i = 0; i < (m_particlesWidthCount - 1) / 2; i++)
	{
		// Determine the ratio of movement
		float ratio = 1.0f - ((float)i / ((float)(m_particlesWidthCount - 1) / 2.0f));
		GetParticle(i, 0)->Move({ ratio, 0.0f, 0.0f });
		GetParticle((m_particlesWidthCount - i - 1), 0)->Move({ -ratio, 0.0f, 0.0f });
	}

	// Calculate the exact distance apart the hooks should be
	float hookDist = (float)m_width / (float)(m_hooks - 1);

	int increment = 0;
	for (int i = 0; i < m_hooks; i++)
	{
		// Calculate a rounded distance so the hook points line up with particle points
		int roundedDist = (int)round(increment * hookDist);

		if (i % 2 == 0) // Hook particle on the left
		{
			HookParticle(GetParticle(roundedDist, 0));
		}
		else // Hook particle on the right
		{
			HookParticle(GetParticle((m_width - roundedDist), 0));

			// Increment the distance every odd/second hook
			increment++;
		}
	}
}
示例#4
0
//------------------------------------------------------------------
// collide joints with each other. Skip particles too close
//------------------------------------------------------------------
bool CChain::SelfCollide()
{
    bool bCollided = false;

    for(int i = 0; i < GetNumParticles(); i ++)
    {
        for (int j = i + m_iSelfCollisionStep; j < GetNumParticles(); j ++)
        {
            bCollided |= GetParticle(i).Collide(GetParticle(j));
        }
    }
    return bCollided;
}
bool ECHARM_multiple_scattering::DoScatteringAxial(ECHARM_distribution *vDistribution, unsigned int vCrystalComponent)
{
    double vEnergyTotal = GetParticle()->GetMomentumVector()->GetModule();
    double vEnergyVariation = vDistribution->GenerateNumber();
    
    vEnergyTotal += vEnergyVariation;
    if(vEnergyTotal>0.){
        double vRandomAngle = 2 * M_PI * drand48();
        GetParticle()->GetMomentumVector()->AddX( vEnergyVariation * cos(vRandomAngle) );
        GetParticle()->GetMomentumVector()->AddY( vEnergyVariation * sin(vRandomAngle) );
        GetParticle()->GetMomentumVector()->ScaleModuleTo(vEnergyTotal);
    }
    else return false;
    
    return true;
}
示例#6
0
void SpringSys::SetInitialVelocity (Point3 p, int index)
{
	if (index < 0 || index > parts.length() ) return;

	GetParticle(index)->SetVel(p);
	return;
}
示例#7
0
//------------------------------------------------------------------------------
//
void gosFX::CardCloud::CreateNewParticle(uint32_t index, Stuff::Point3D* translation)
{
	// Check_Object(this);
	//
	//-------------------------------------------------------------------
	// Let our parent do creation, then turn on the particle in the cloud
	//-------------------------------------------------------------------
	//
	SpinningCloud::CreateNewParticle(index, translation);
	m_cloudImplementation->TurnOn(index);
	_ASSERT(m_cloudImplementation->IsOn(index));
	//
	//-----------------------------
	// Figure out the particle size
	//-----------------------------
	//
	Specification* spec = GetSpecification();
	Check_Object(spec);
	Particle* particle = GetParticle(index);
	Check_Object(particle);
	particle->m_halfY = spec->m_halfHeight.ComputeValue(m_age, particle->m_seed);
	particle->m_halfX =
		particle->m_halfY * spec->m_aspectRatio.ComputeValue(m_age, particle->m_seed);
	particle->m_radius =
		Stuff::Sqrt(particle->m_halfX * particle->m_halfX + particle->m_halfY * particle->m_halfY);
}
//------------------------------------------------------------------------------
//
bool
	gosFX::ShapeCloud::AnimateParticle(
		unsigned index,
		const Stuff::LinearMatrix4D *world_to_new_local,
		Stuff::Time till
	)
{
	Check_Object(this);

	//
	//-----------------------------------------
	// Animate the parent then get our pointers
	//-----------------------------------------
	//
	if (!SpinningCloud::AnimateParticle(index, world_to_new_local, till))
		return false;
	Set_Statistic(Shape_Count, Shape_Count+1);
	Specification *spec = GetSpecification();
	Check_Object(spec);
	Particle *particle = GetParticle(index);
	Check_Object(particle);
	Stuff::Scalar seed = particle->m_seed;
	Stuff::Scalar age = particle->m_age;

	//
	//------------------
	// Animate the color
	//------------------
	//
	particle->m_color.red = spec->m_pRed.ComputeValue(age, seed);
	particle->m_color.green = spec->m_pGreen.ComputeValue(age, seed);
	particle->m_color.blue = spec->m_pBlue.ComputeValue(age, seed);
	particle->m_color.alpha = spec->m_pAlpha.ComputeValue(age, seed);
	return true;
}
示例#9
0
void SpringSys::SetInitialBoneStates(Tab<Matrix3> boneTMs)
{
	for (int x = 0; x< GetParticles()->length(); x++)
	{
		SSParticle *p = GetParticle(x);
		for (int tmId = 0; tmId< boneTMs.Count(); tmId++)
		{
			for (int i=0;i<p->GetSprings()->length();i++)
			{
				if (tmId == p->GetSpring(i)->GetPointConstraint()->GetIndex())
				{
					if (tmId == 0) 
						p->GetSpring(i)->SetLength(Point3::Origin);
					else p->GetSpring(i)->SetLength( initPosTab[x] * Inverse(boneTMs[tmId]) );
					
					p->GetSpring(i)->GetPointConstraint()->SetPos(initPosTab[x]);
					p->GetSpring(i)->GetPointConstraint()->SetVel(Point3::Origin);
				}
			}
			if (frameCache.bone.length() <= tmId) 
			{
				SSConstraintPoint contBone = SSConstraintPoint(tmId);
				frameCache.bone.append(contBone);
			}
		}
		//frameCache.bone.SetCount(tmId+1);
	}
}
示例#10
0
void SpringSys::SetInitialPosition (Point3 p, int index)
{
	if (index < 0 || index > parts.length() ) return;

	initPosTab[index] = p;
	GetParticle(index)->SetPos(p);
	return;
}
double ECHARM_multiple_scattering_functions::EvaluateSingleScatteringEnergyVariationConstantBiryukov() //!< Biryukov book INTEGRATED OVER T [I,T_max]!!
{
    double EnergyLoss = (4.0 * M_PI * pow(cElectronRadius,2.0) * cElectronMass);
    EnergyLoss *= (pow(fabs(fParticle->GetZ()),2.0)*fCrystal->GetZ());
    EnergyLoss /= ( 2.0 * pow(GetParticle()->GetBeta(),2.0) );
    EnergyLoss *= fCrossedMaterialLength;
    EnergyLoss *= fCrystal->GetNucleiDensity();
    return EnergyLoss;
}
示例#12
0
//_____________________________________________________________________________
TParticle*  amsvmc_MCStack::GetCurrentTrack() const 
{
/// \return  The current track particle

  TParticle* current = GetParticle(fCurrentTrack);

  if (!current)    
    Warning("GetCurrentTrack", "Current track not found in the stack");

  return current;
}  
示例#13
0
//_____________________________________________________________________________
void amsvmc_MCStack::Print(Option_t* /*option*/) const 
{
/// Print info for all particles.

//   cout << "amsvmc_MCStack Info  " << endl;
//   cout << "Total number of particles:   " <<  GetNtrack() << endl;
//   cout << "Number of primary particles: " <<  GetNprimary() << endl;

  for (Int_t i=0; i<GetNtrack(); i++)
    GetParticle(i)->Print();
}
示例#14
0
void CChain::SetChain(const Vector& P0, const Vector& P1, int iNumParticles, int iRigidity, float fParticleRadius, float fParticleMass)
{
    Free();

    Allocate(iNumParticles, iNumParticles-1);

    if (iNumParticles < 2)
        return;

    if (iRigidity <= 0)
        iRigidity = 1;

    SetRigidity(iRigidity);

    //-----------------------------------------------------------
    // copy particles
    //-----------------------------------------------------------
    Vector P = P0;
    Vector D = (P0 - P1) / ((float) iNumParticles);

    for(int i = 0; i < iNumParticles; i ++)
    {
        AddParticle(CParticle(P, fParticleRadius, (i != 0)? fParticleMass : 0.0f));

        P += D;
    }

    //------------------------------------------------------------------
    // link particles together
    //------------------------------------------------------------------
    for(int i = 0; i < iNumParticles-1; i ++)
    {
        AddConstraint(CLinConstraint(&GetParticle(i), &GetParticle(i+1)));

        P += D;
    }

    ComputeBoundingSphere();

    m_iSelfCollisionStep = 2;
}
示例#15
0
void Physics_Cloth::AddForce(v3float _force, eForceType _forceType, bool _selected)
{
	switch (_forceType)
	{
	case FT_GENERIC: // Adds the same generic force to each particle
	{
		for (int i = 0; i < m_particleCount; i++)
		{
			if (m_pParticles[i].GetSelectedState() == _selected)
			{
				m_pParticles[i].AddForce(_force);
			}
		}
	}
	break;
	case FT_WIND: // Add a wind force that bases the strength of the force on the normal of triangles
	{
		// Multiply the force direction by the current wind speed
		_force = _force.Normalise() * m_windSpeed;

		// Cycle through the particles based on the rows and columns (Due to using a triangle strip topology)
		for (int x = 0; x < m_particlesWidthCount - 1; x++)
		{
			for (int y = 0; y < m_particlesHeightCount - 1; y++)
			{
				// Add wind force to both triangles in the current grid selection
				AddWindForceForTri(GetParticle(x + 1, y + 1), GetParticle(x, y + 1), GetParticle(x, y), _force);
				AddWindForceForTri(GetParticle(x, y), GetParticle(x + 1, y), GetParticle(x + 1, y + 1), _force);
			}
		}
	}
	break;
	default:break;
	}
}
示例#16
0
void JelloMesh::DrawSprings(double a)
{
    const ParticleGrid& g = m_vparticles;
    glBegin(GL_LINES);
    for (unsigned int i = 0; i < m_vsprings.size(); i++)
    {
        if (!(m_vsprings[i].m_type & m_drawflags)) continue;
        if (isInterior(m_vsprings[i])) continue;

        switch (m_vsprings[i].m_type)
        {
        case BEND:       glColor4f(1.0, 1.0, 0.0, a); break;
        case STRUCTURAL: glColor4f(1.0, 1.0, 0.0, a); break;
        case SHEAR:      glColor4f(0.0, 1.0, 1.0, a); break;
        };

        vec3 p1 = GetParticle(g, m_vsprings[i].m_p1).position;
        vec3 p2 = GetParticle(g, m_vsprings[i].m_p2).position;
        glVertex3f(p1[0], p1[1], p1[2]);
        glVertex3f(p2[0], p2[1], p2[2]);
    }
    glEnd();
}
示例#17
0
void JelloMesh::ResolveCollisions(ParticleGrid& grid)
{
    for(unsigned int i = 0; i < m_vcollisions.size(); i++)
    {
        Intersection& result = m_vcollisions[i];
        Particle& pt = GetParticle(grid, result.m_p);
        vec3 normal = result.m_normal;
        float dist = result.m_distance;

        // TODO
		if(pt.velocity*normal<0) 
			pt.force += g_penaltyKs*normal*dist + g_penaltyKd*(pt.velocity*normal)*normal;
	}
}
示例#18
0
void JelloMesh::ResolveContacts(ParticleGrid& grid)
{
    for (unsigned int i = 0; i < m_vcontacts.size(); i++)
    {
       // const Intersection& contact = m_vcontacts[i];
	   Intersection& contact = m_vcontacts[i];
       Particle& p = GetParticle(grid, contact.m_p);
       vec3 normal = contact.m_normal; 
	   float dist = contact.m_distance;

       // TODO
	   p.position += normal*dist;
	   p.velocity += 2*(-p.velocity*normal)*normal;
    }
}
void ECHARM_simulation_integration_averaged::PreInitializeEnergyToDechannel()
{
    double vTempEnergy;
    double vX;
    fPlanarEnergyToDechannel.clear();
    
    double vPotentialBarrier = GetStrip()->GetCrystal()->GetPlanarElectricCharacteristic(0.0,0);

#ifdef ROOT_
    std::string vHistoName = "hEnergyToDechannel_prf" + GetStrip()->GetRadiusValueAsStringText() + "_" + GetStrip()->GetLengthValueAsStringText();
    TH1F *hEnergyToDechannel = new TH1F( vHistoName.c_str(),"hEnergyToDechannel;Interplanar Distance [#AA]",GetIntegrationStepNumberPlanar(),0.,GetStrip()->GetCrystal()->GetDirectPeriodPlanar() );
#endif
    
    for(unsigned int i = 0; i < GetIntegrationStepNumberPlanar(); i++)
    {
        vX = double(i) / double(GetIntegrationStepNumberPlanar()) * GetStrip()->GetCrystal()->GetDirectPeriodPlanar();
        vTempEnergy = GetStrip()->GetCrystal()->GetPlanarElectricCharacteristic( vX , 0);
        
        //std::cout << vTempEnergy << " ";
        if( StripIsBentX() ) vTempEnergy += ( GetParticle()->GetMomentumVector()->GetZ() * GetParticle()->GetBeta()  * vX / GetStrip()->GetCurvatureRadius()->GetX() );
        //std::cout << GetParticle()->GetMomentumVector()->GetZ() << " " << GetParticle()->GetBeta() << " " << GetStrip()->GetCurvatureRadius()->GetX() << " " << vX << " ";

        vTempEnergy -= vPotentialBarrier;
        vTempEnergy += ( GetParticle()->GetBeta() * fSquare(GetParticle()->GetMomentumVector()->GetX()) / GetParticle()->GetMomentumVector()->GetZ());
        
        //std::cout << vTempEnergy << " ";
        
        if(vTempEnergy > 0.0) vTempEnergy = -0.;
        vTempEnergy *= (-1.);
        fPlanarEnergyToDechannel.push_back(vTempEnergy);
        //std::cout << vTempEnergy << std::endl; // DA TOGLIERE
#ifdef ROOT_
        hEnergyToDechannel->SetBinContent(i+1,vTempEnergy);
#endif
    }
}
示例#20
0
void JelloMesh::EulerIntegrate(double dt)
{
	//TODO
	for (int i = 0; i < m_rows+1; i++)
	{
		for (int j = 0; j < m_cols+1; j++)
		{
			for (int k = 0; k < m_stacks+1; k++)
			{
				Particle& p = GetParticle(m_vparticles, i,j,k);
				p.velocity = p.velocity + dt*p.force/p.mass;
				p.position = p.position + dt*p.velocity;
			}
		}
	}
}
示例#21
0
void JelloMesh::CheckForCollisions(ParticleGrid& grid, const World& world)
{
    m_vcontacts.clear();
    m_vcollisions.clear();

    for (int i = 0; i < m_rows+1; i++)
    {
        for (int j = 0; j < m_cols+1; j++)
        {
            for (int k = 0; k < m_stacks+1; k++)
            {
                Particle& p = GetParticle(grid, i,j,k);

                // 1. Check collisions with world objects 
                for (unsigned int l = 0; l < world.m_shapes.size(); l++)
                {
                    Intersection intersection;
                    if (world.m_shapes[l]->GetType() == World::CYLINDER && 
                        CylinderIntersection(p, (World::Cylinder*) world.m_shapes[l], intersection))
                    {
						if(intersection.m_type == CONTACT) m_vcontacts.push_back(intersection);
						else m_vcollisions.push_back(intersection);
                    }
                    else if (world.m_shapes[l]->GetType() == World::GROUND && 
                        FloorIntersection(p, intersection))
                    {
                        if(intersection.m_type == CONTACT) m_vcontacts.push_back(intersection);
						else m_vcollisions.push_back(intersection);
                    }
					else if (world.m_shapes[l]->GetType() == World::SPHERE && 
                        SphereIntersection(p, (World::Sphere*) world.m_shapes[l], intersection))
                    {
                        if(intersection.m_type == CONTACT) m_vcontacts.push_back(intersection);
						else m_vcollisions.push_back(intersection);
                    }
					if (world.m_shapes[l]->GetType() == World::CUBE && 
                        CubeIntersection(p, (World::Cube*) world.m_shapes[l], intersection))
                    {
						if(intersection.m_type == CONTACT) m_vcontacts.push_back(intersection);
						else m_vcollisions.push_back(intersection);
                    }
                }
            }
        }
    }
}
示例#22
0
void JelloMesh::DrawCollisionNormals()
{
    const ParticleGrid& g = m_vparticles;
    glBegin(GL_LINES);
    glColor3f(0.0, 1.0, 0.0);
    for(unsigned int i = 0; i < m_vcollisions.size(); i++)
    {
       Intersection intersection = m_vcollisions[i];
       if (isInterior(intersection.m_p)) continue;

       const Particle& pt = GetParticle(g, intersection.m_p);
       vec3 normal = intersection.m_normal;
       vec3 end = pt.position + 0.2 * normal;
       glVertex3f(pt.position[0], pt.position[1], pt.position[2]);
       glVertex3f(end[0], end[1], end[2]);
    }     
    glEnd();
}
示例#23
0
//------------------------------------------------------------------------------
//
void
	gosFX::ShapeCloud::CreateNewParticle(
		unsigned index,
		Stuff::Point3D *translation
	)
{
	Check_Object(this);

	//
	//-------------------------------------------------------------------
	// Let our parent do creation, then turn on the particle in the cloud
	//-------------------------------------------------------------------
	//
	SpinningCloud::CreateNewParticle(index, translation);
	Specification *spec = GetSpecification();
	Check_Object(spec);
	Particle *particle = GetParticle(index);
	Check_Object(particle);
	particle->m_radius = spec->m_radius;
}
AxisAlignedBox MeteorProjectile::GetBoundingBox()
{
	return ParticleSystem::GetBoundingBox();

	// Uses one random particles distance from the center.
	GLib::Particle* particle = GetParticle(1);
	if(particle == nullptr)
		return XNA::AxisAlignedBox();

	XMFLOAT3 pos = particle->GetPosition();
	XMFLOAT3 diff = pos - GetPosition();
	float dist = sqrt(diff.x*diff.x + diff.y * diff.y + diff.z*diff.z);

	XNA::AxisAlignedBox box;
	box.Center = GetPosition();
	box.Extents = XMFLOAT3(dist, dist, dist);

	char buffer[244];
	sprintf(buffer, "DIST MFER: %f\n", dist);
	OutputDebugString(buffer);

	return box;
}
double ECHARM_simulation_integration_averaged::GetElectricalCharactericticPlanarAveragedOverOnePeriod(unsigned int vType)
{
    ECHARM_threevector *vPositionStart = new ECHARM_threevector();
    ECHARM_threevector *vMomentumStart = new ECHARM_threevector();
    
    vPositionStart->CopyFrom(GetParticle()->GetPositionVector());
    vMomentumStart->CopyFrom(GetParticle()->GetMomentumVector());

    double vDensity = 0.0;
    do
    {
        UpdateStepLengthPlanar();
        DoIntegrationStepPlanarVelocityVerlet();
        vDensity += GetStrip()->GetCrystal()->GetPlanarElectricCharacteristic(GetParticle()->GetPositionVector()->GetX(),vType) * GetStepLength();
    }
    while ( GetParticle()->GetPositionVector()->GetZ() < GetStrip()->GetDimension()->GetZ());
    
    GetParticle()->GetPositionVector()->CopyFrom(vPositionStart);
    GetParticle()->GetMomentumVector()->CopyFrom(vMomentumStart);
    
    return vDensity;
}
示例#26
0
//------------------------------------------------------------------------------
//
bool
gosFX::PointCloud::AnimateParticle(
	uint32_t index,
	const Stuff::LinearMatrix4D* world_to_new_local,
	Stuff::Time till
)
{
	Check_Object(this);
	//
	//-----------------------------------------------------------------------
	// If this cloud is unparented, we need to transform the point from local
	// space into world space and set the internal position/velocity pointers
	// to these temporary values
	//-----------------------------------------------------------------------
	//
	Particle* particle = GetParticle(index);
	Check_Object(particle);
	float age = particle->m_age;
	if(age >= 1.0f)
		return false;
	Set_Statistic(Point_Count, Point_Count + 1);
	Stuff::Vector3D* velocity = &particle->m_localLinearVelocity;
	Stuff::Point3D* translation = &m_P_localTranslation[index];
	int32_t sim_mode = GetSimulationMode();
	if(sim_mode == DynamicWorldSpaceSimulationMode)
	{
		Check_Object(translation);
		Check_Object(velocity);
		particle->m_worldLinearVelocity.Multiply(*velocity, m_localToWorld);
		particle->m_worldTranslation.Multiply(*translation, m_localToWorld);
		translation = &particle->m_worldTranslation;
		velocity = &particle->m_worldLinearVelocity;
	}
	Check_Object(translation);
	Check_Object(velocity);
	//
	//------------------------------------------------------------------
	// First, calculate the drag on the particle.  Drag can never assist
	// velocity
	//------------------------------------------------------------------
	//
	float seed = particle->m_seed;
	Specification* spec = GetSpecification();
	Check_Object(spec);
	Stuff::Vector3D ether;
	ether.x = spec->m_pEtherVelocityX.ComputeValue(age, seed);
	ether.y = spec->m_pEtherVelocityY.ComputeValue(age, seed);
	ether.z = spec->m_pEtherVelocityZ.ComputeValue(age, seed);
	Stuff::Vector3D accel(Stuff::Vector3D::Identity);
	//
	//-------------------------------------------------------------------
	// Deal with pseudo-world simulation.  In this mode, we interpret the
	// forces as if they are already in worldspace, and we transform them
	// back to local space
	//-------------------------------------------------------------------
	//
	float drag = -spec->m_pDrag.ComputeValue(age, seed);
	Max_Clamp(drag, 0.0f);
	if(sim_mode == StaticWorldSpaceSimulationMode)
	{
		Stuff::LinearMatrix4D world_to_effect;
		world_to_effect.Invert(m_localToWorld);
		Stuff::Vector3D local_ether;
		local_ether.MultiplyByInverse(ether, world_to_effect);
		Stuff::Vector3D rel_vel;
		rel_vel.Subtract(*velocity, local_ether);
		accel.Multiply(rel_vel, drag);
		//
		//-----------------------------------------
		// Now, add in acceleration of the particle
		//-----------------------------------------
		//
		Stuff::Vector3D world_accel;
		world_accel.x = spec->m_pAccelerationX.ComputeValue(age, seed);
		world_accel.y = spec->m_pAccelerationY.ComputeValue(age, seed);
		world_accel.z = spec->m_pAccelerationZ.ComputeValue(age, seed);
		Stuff::Vector3D local_accel;
		local_accel.Multiply(world_accel, world_to_effect);
		accel += local_accel;
	}
	//
	//----------------------------------------------------------------------
	// Otherwise, just add the forces in the same space the particles are in
	//----------------------------------------------------------------------
	//
	else
	{
		Stuff::Vector3D rel_vel;
		rel_vel.Subtract(*velocity, ether);
		accel.Multiply(rel_vel, drag);
		//
		//-----------------------------------------
		// Now, add in acceleration of the particle
		//-----------------------------------------
		//
		accel.x += spec->m_pAccelerationX.ComputeValue(age, seed);
		accel.y += spec->m_pAccelerationY.ComputeValue(age, seed);
		accel.z += spec->m_pAccelerationZ.ComputeValue(age, seed);
	}
	//
	//-------------------------------------------------
	// Compute the particle's new velocity and position
	//-------------------------------------------------
	//
	float time_slice =
		static_cast<float>(till - m_lastRan);
	velocity->AddScaled(*velocity, accel, time_slice);
	translation->AddScaled(*translation, *velocity, time_slice);
	//
	//---------------------------------------------------------------------
	// If we are unparented, we need to transform the velocity and position
	// data back into the NEW local space
	//---------------------------------------------------------------------
	//
	if(sim_mode == DynamicWorldSpaceSimulationMode)
	{
		Check_Object(world_to_new_local);
		particle->m_localLinearVelocity.Multiply(
			particle->m_worldLinearVelocity,
			*world_to_new_local
		);
		m_P_localTranslation[index].Multiply(
			particle->m_worldTranslation,
			*world_to_new_local
		);
	}
	//
	//------------------
	// Animate the color
	//------------------
	//
	Check_Pointer(m_P_color);
	m_P_color[index].red = spec->m_pRed.ComputeValue(age, seed);
	m_P_color[index].green = spec->m_pGreen.ComputeValue(age, seed);
	m_P_color[index].blue = spec->m_pBlue.ComputeValue(age, seed);
	m_P_color[index].alpha = spec->m_pAlpha.ComputeValue(age, seed);
	return true;
}
示例#27
0
bool Physics_Cloth::ResetCloth()
{
	// Clear Memory
	ReleaseCloth();
	ReleaseSelected();
	m_contraints.clear();
	m_nextIndex = 0;

	if (m_initialisedParticles == false)
	{
		ReleasePtr(m_pMesh);
		ReleasePtrArray(m_pParticles);

		// Create memory for all the particles
		m_particleCount = m_particlesWidthCount * m_particlesHeightCount;
		m_pParticles = new Physics_Particle[m_particleCount];
		m_pVertices = new TVertexColor[m_particleCount];		

		// Calculate how many indices there are with be based on how many particles there are using line list
		int immediateConstraintCount = (m_particlesWidthCount - 1) * (m_particlesHeightCount - 1) * 4 + (m_particlesWidthCount - 1) + (m_particlesHeightCount - 1);
		int secondaryConstraintCount = 0;
		if (m_complexWeave == true)
		{
			// Calculate the secondary indices count only if the weave is set to complex
			secondaryConstraintCount = (m_particlesWidthCount - 2) * (m_particlesHeightCount - 2) * 4 + ((m_particlesWidthCount - 2) * 2) + ((m_particlesHeightCount - 2) * 2);
		}
		
		// Create the indices buffer with the amount of calculated constraints
		m_indexCount = (immediateConstraintCount + secondaryConstraintCount) * 2;
		m_pIndices = new DWORD[m_indexCount];
	}
	
	// Cycle through all the particles
	for (int col = 0; col < m_particlesWidthCount; col++)
	{
		for (int row = 0; row < m_particlesHeightCount; row++)
		{
			// Calculate the position based on the particles row and column
			v3float pos;
			pos.x = m_width * (col / (float)m_width) - ((float)m_width / 2.0f);
			pos.y = -m_height * (row / (float)m_height) + ((float)m_height / 2.0f);
			pos.z = 0.0f;
			int index = row * m_particlesWidthCount + col;

			if (m_initialisedParticles == false)
			{
				// First time. Initialise			
				m_pVertices[index] = { { pos.x, pos.y, pos.z }, d3dxColors::White };
				VALIDATE(m_pParticles[index].Initialise(index, &m_pVertices[index], pos, m_timeStep, m_damping));
			}
			else
			{
				// Particle has already been initialized so just reset the position
				m_pParticles[index].Reset();
				m_pParticles[index].SetPosition(pos, true);
				m_pVertices[index].color = d3dxColors::White;
			}
		}
	}

	// Connect Particles that are immediately to the right and below (include diagonals)
	for (int col = 0; col < m_particlesWidthCount; col++)
	{
		for (int row = 0; row < m_particlesHeightCount; row++)
		{
			// Particle to the Right exists
			if (col < m_particlesWidthCount - 1)
			{
				VALIDATE(MakeConstraint(GetParticleIndex(col, row), GetParticleIndex(col + 1, row), true));
				
				// Add the constraint index to each attached particle
				GetParticle(col, row)->AddContraintIndex(m_contraints.size() - 1);
				GetParticle(col + 1, row)->AddContraintIndex(m_contraints.size() - 1);
			}
	
			// Particle below exists
			if (row < m_particlesHeightCount - 1)
			{
				VALIDATE(MakeConstraint(GetParticleIndex(col, row), GetParticleIndex(col, row + 1), true));

				// Add the constraint index to each attached particle
				GetParticle(col, row)->AddContraintIndex(m_contraints.size() - 1);
				GetParticle(col, row + 1)->AddContraintIndex(m_contraints.size() - 1);
			}
	
			// Particle to the right and below exists
			if ((col < m_particlesWidthCount - 1) && (row < m_particlesHeightCount - 1))
			{
				VALIDATE(MakeConstraint(GetParticleIndex(col, row), GetParticleIndex(col + 1, row + 1), true));

				// Add the constraint index to each attached particle
				GetParticle(col, row)->AddContraintIndex(m_contraints.size() - 1);
				GetParticle(col + 1, row + 1)->AddContraintIndex(m_contraints.size() - 1);

				VALIDATE(MakeConstraint(GetParticleIndex(col + 1, row), GetParticleIndex(col, row + 1), true));

				// Add the constraint index to each attached particle
				GetParticle(col + 1, row)->AddContraintIndex(m_contraints.size() - 1);
				GetParticle(col, row + 1)->AddContraintIndex(m_contraints.size() - 1);
			}
		}
	}

	if (m_complexWeave == true)
	{
		// Connect Particles the are one step further away than previous loop
		for (int col = 0; col < m_particlesWidthCount; col++)
		{
			for (int row = 0; row < m_particlesHeightCount; row++)
			{
				// Particle to the Right exists
				if (col < m_particlesWidthCount - 2)
				{
					VALIDATE(MakeConstraint(GetParticleIndex(col, row), GetParticleIndex(col + 2, row), false));

					// Add the constraint index to each attached particle
					GetParticle(col, row)->AddContraintIndex(m_contraints.size() - 1);
					GetParticle(col + 2, row)->AddContraintIndex(m_contraints.size() - 1);
				}

				// Particle below exists
				if (row < m_particlesHeightCount - 2)
				{
					VALIDATE(MakeConstraint(GetParticleIndex(col, row), GetParticleIndex(col, row + 2), false));

					// Add the constraint index to each attached particle
					GetParticle(col, row)->AddContraintIndex(m_contraints.size() - 1);
					GetParticle(col, row + 2)->AddContraintIndex(m_contraints.size() - 1);
				}

				// Particle to the right and below exists
				if ((col < m_particlesWidthCount - 2) && (row < m_particlesHeightCount - 2))
				{
					VALIDATE(MakeConstraint(GetParticleIndex(col, row), GetParticleIndex(col + 2, row + 2), false));

					// Add the constraint index to each attached particle
					GetParticle(col, row)->AddContraintIndex(m_contraints.size() - 1);
					GetParticle(col + 2, row + 2)->AddContraintIndex(m_contraints.size() - 1);

					VALIDATE(MakeConstraint(GetParticleIndex(col + 2, row), GetParticleIndex(col, row + 2), false));

					// Add the constraint index to each attached particle
					GetParticle(col + 2, row)->AddContraintIndex(m_contraints.size() - 1);
					GetParticle(col, row + 2)->AddContraintIndex(m_contraints.size() - 1);
				}
			}
		}
	}
	
	if (m_initialisedParticles == false)
	{
		// Create a new Cloth Mesh
		m_pMesh = new DX10_Mesh();
		VALIDATE(m_pMesh->InitialiseCloth(m_pRenderer, m_pVertices, m_pIndices, m_particleCount, m_indexCount, sizeof(TVertexColor), D3D10_PRIMITIVE_TOPOLOGY_LINELIST, D3D10_USAGE_DYNAMIC, D3D10_USAGE_DYNAMIC));
	}

	// Create the hooks and pin the cloth
	CreateHooks();

	// Add a wind force of 1 down the Z axis to settle the cloth
	AddForce({ 0.0f, 0.0f, 1.0f }, FT_GENERIC, false);
	Process(CT_NONE);

	m_initialisedParticles = true;
	return true;
}
示例#28
0
//------------------------------------------------------------------------------
//
void gosFX::CardCloud::Draw(DrawInfo* info)
{
	// Check_Object(this);
	Check_Object(info);
	//
	//---------------------------------------------------------
	// If we have active particles, set up the draw information
	//---------------------------------------------------------
	//
	if (m_activeParticleCount)
	{
		MidLevelRenderer::DrawEffectInformation dInfo;
		dInfo.effect		= m_cloudImplementation;
		Specification* spec = GetSpecification();
		Check_Object(spec);
		dInfo.state.Combine(info->m_state, spec->m_state);
		dInfo.clippingFlags = info->m_clippingFlags;
		Stuff::LinearMatrix4D local_to_world;
		local_to_world.Multiply(m_localToParent, *info->m_parentToWorld);
		dInfo.effectToWorld = &local_to_world;
		//
		//--------------------------------------------------------------
		// Check the orientation mode.  The first case is XY orientation
		//--------------------------------------------------------------
		//
		uint32_t i;
		uint32_t vert = 0;
		if (spec->m_alignZUsingX)
		{
			if (spec->m_alignZUsingY)
			{
				//
				//-----------------------------------------
				// Get the camera location into local space
				//-----------------------------------------
				//
				Stuff::Point3D camera_in_world(info->m_clipper->GetCameraToWorldMatrix());
				Stuff::Point3D camera_in_cloud;
				camera_in_cloud.MultiplyByInverse(camera_in_world, local_to_world);
				//
				//--------------------------------------
				// Spin through all the active particles
				//--------------------------------------
				//
				for (i = 0; i < m_activeParticleCount; i++)
				{
					Particle* particle = GetParticle(i);
					Check_Object(particle);
					if (particle->m_age < 1.0f)
					{
						//
						//--------------------------------
						// Build the local to cloud matrix
						//--------------------------------
						//
						Stuff::Vector3D direction_in_cloud;
						direction_in_cloud.Subtract(camera_in_cloud, particle->m_localTranslation);
						Stuff::LinearMatrix4D card_to_cloud;
						card_to_cloud.BuildRotation(particle->m_localRotation);
						card_to_cloud.AlignLocalAxisToWorldVector(
							direction_in_cloud, Stuff::Z_Axis, Stuff::Y_Axis, Stuff::X_Axis);
						card_to_cloud.BuildTranslation(particle->m_localTranslation);
						//
						//-------------------------------------------------
						// Figure out the scale, then build the four points
						//-------------------------------------------------
						//
						float scale = particle->m_scale;
						m_P_vertices[vert++].Multiply(Stuff::Point3D(scale * particle->m_halfX,
														  -scale * particle->m_halfY, 0.0f),
							card_to_cloud);
						m_P_vertices[vert++].Multiply(Stuff::Point3D(-scale * particle->m_halfX,
														  -scale * particle->m_halfY, 0.0f),
							card_to_cloud);
						m_P_vertices[vert++].Multiply(Stuff::Point3D(-scale * particle->m_halfX,
														  scale * particle->m_halfY, 0.0f),
							card_to_cloud);
						m_P_vertices[vert++].Multiply(Stuff::Point3D(scale * particle->m_halfX,
														  scale * particle->m_halfY, 0.0f),
							card_to_cloud);
					}
					else
						vert += 4;
				}
			}
			//
			//-----------------------
			// Handle X-only rotation
			//-----------------------
			//
			else
			{
				//
				//-----------------------------------------
				// Get the camera location into local space
				//-----------------------------------------
				//
				Stuff::Point3D camera_in_world(info->m_clipper->GetCameraToWorldMatrix());
				Stuff::Point3D camera_in_cloud;
				camera_in_cloud.MultiplyByInverse(camera_in_world, local_to_world);
				//
				//--------------------------------------
				// Spin through all the active particles
				//--------------------------------------
				//
				for (i = 0; i < m_activeParticleCount; i++)
				{
					Particle* particle = GetParticle(i);
					Check_Object(particle);
					if (particle->m_age < 1.0f)
					{
						//
						//--------------------------------
						// Build the local to cloud matrix
						//--------------------------------
						//
						Stuff::Vector3D direction_in_cloud;
						direction_in_cloud.Subtract(camera_in_cloud, particle->m_localTranslation);
						Stuff::LinearMatrix4D card_to_cloud;
						card_to_cloud.BuildRotation(particle->m_localRotation);
						card_to_cloud.AlignLocalAxisToWorldVector(
							direction_in_cloud, Stuff::Z_Axis, Stuff::X_Axis, -1);
						card_to_cloud.BuildTranslation(particle->m_localTranslation);
						//
						//-------------------------------------------------
						// Figure out the scale, then build the four points
						//-------------------------------------------------
						//
						float scale = particle->m_scale;
						m_P_vertices[vert++].Multiply(Stuff::Point3D(scale * particle->m_halfX,
														  -scale * particle->m_halfY, 0.0f),
							card_to_cloud);
						m_P_vertices[vert++].Multiply(Stuff::Point3D(-scale * particle->m_halfX,
														  -scale * particle->m_halfY, 0.0f),
							card_to_cloud);
						m_P_vertices[vert++].Multiply(Stuff::Point3D(-scale * particle->m_halfX,
														  scale * particle->m_halfY, 0.0f),
							card_to_cloud);
						m_P_vertices[vert++].Multiply(Stuff::Point3D(scale * particle->m_halfX,
														  scale * particle->m_halfY, 0.0f),
							card_to_cloud);
					}
					else
						vert += 4;
				}
			}
		}
		//
		//-------------------------------------------------------
		// Each matrix needs to be aligned to the camera around Y
		//-------------------------------------------------------
		//
		else if (spec->m_alignZUsingY)
		{
			//
			//-----------------------------------------
			// Get the camera location into local space
			//-----------------------------------------
			//
			Stuff::Point3D camera_in_world(info->m_clipper->GetCameraToWorldMatrix());
			Stuff::Point3D camera_in_cloud;
			camera_in_cloud.MultiplyByInverse(camera_in_world, local_to_world);
			//
			//--------------------------------------
			// Spin through all the active particles
			//--------------------------------------
			//
			for (i = 0; i < m_activeParticleCount; i++)
			{
				Particle* particle = GetParticle(i);
				Check_Object(particle);
				if (particle->m_age < 1.0f)
				{
					//
					//--------------------------------
					// Build the local to cloud matrix
					//--------------------------------
					//
					Stuff::Vector3D direction_in_cloud;
					direction_in_cloud.Subtract(camera_in_cloud, particle->m_localTranslation);
					Stuff::LinearMatrix4D card_to_cloud;
					card_to_cloud.BuildRotation(particle->m_localRotation);
					card_to_cloud.AlignLocalAxisToWorldVector(
						direction_in_cloud, Stuff::Z_Axis, Stuff::Y_Axis, -1);
					card_to_cloud.BuildTranslation(particle->m_localTranslation);
					//
					//-------------------------------------------------
					// Figure out the scale, then build the four points
					//-------------------------------------------------
					//
					float scale = particle->m_scale;
					m_P_vertices[vert++].Multiply(
						Stuff::Point3D(scale * particle->m_halfX, -scale * particle->m_halfY, 0.0f),
						card_to_cloud);
					m_P_vertices[vert++].Multiply(Stuff::Point3D(-scale * particle->m_halfX,
													  -scale * particle->m_halfY, 0.0f),
						card_to_cloud);
					m_P_vertices[vert++].Multiply(
						Stuff::Point3D(-scale * particle->m_halfX, scale * particle->m_halfY, 0.0f),
						card_to_cloud);
					m_P_vertices[vert++].Multiply(
						Stuff::Point3D(scale * particle->m_halfX, scale * particle->m_halfY, 0.0f),
						card_to_cloud);
				}
				else
					vert += 4;
			}
		}
		//
		//---------------------------------------------------------------
		// No alignment is necessary, so just multiply out all the active
		// particles
		//---------------------------------------------------------------
		//
		else
		{
			for (i = 0; i < m_activeParticleCount; i++)
			{
				Particle* particle = GetParticle(i);
				Check_Object(particle);
				if (particle->m_age < 1.0f)
				{
					//
					//--------------------------------
					// Build the local to cloud matrix
					//--------------------------------
					//
					Stuff::LinearMatrix4D card_to_cloud;
					card_to_cloud.BuildRotation(particle->m_localRotation);
					card_to_cloud.BuildTranslation(particle->m_localTranslation);
					//
					//-------------------------------------------------
					// Figure out the scale, then build the four points
					//-------------------------------------------------
					//
					float scale = particle->m_scale;
					m_P_vertices[vert++].Multiply(
						Stuff::Point3D(scale * particle->m_halfX, -scale * particle->m_halfY, 0.0f),
						card_to_cloud);
					m_P_vertices[vert++].Multiply(Stuff::Point3D(-scale * particle->m_halfX,
													  -scale * particle->m_halfY, 0.0f),
						card_to_cloud);
					m_P_vertices[vert++].Multiply(
						Stuff::Point3D(-scale * particle->m_halfX, scale * particle->m_halfY, 0.0f),
						card_to_cloud);
					m_P_vertices[vert++].Multiply(
						Stuff::Point3D(scale * particle->m_halfX, scale * particle->m_halfY, 0.0f),
						card_to_cloud);
				}
				else
					vert += 4;
			}
		}
		//
		//---------------------
		// Now just do the draw
		//---------------------
		//
		info->m_clipper->DrawEffect(&dInfo);
	}
	SpinningCloud::Draw(info);
}
示例#29
0
//------------------------------------------------------------------------------
//
void gosFX::ShapeCloud::Draw(DrawInfo *info)
{
	Check_Object(this);
	Check_Object(info);
	Check_Object(info->m_parentToWorld);

	//
	//----------------------------
	// Set up the common draw info
	//----------------------------
	//
	if (m_activeParticleCount)
	{
		MidLevelRenderer::DrawScalableShapeInformation dinfo;
		MidLevelRenderer::MLRShape *shape = GetSpecification()->m_shape;
		dinfo.clippingFlags.SetClippingState(0x3f);
		dinfo.worldToShape = NULL;
		Specification *spec = GetSpecification();
		Check_Object(spec);
		dinfo.state.Combine(info->m_state, spec->m_state);
		dinfo.activeLights = NULL;
		dinfo.nrOfActiveLights = 0;
		dinfo.shape = shape;
		Stuff::LinearMatrix4D local_to_world;
		local_to_world.Multiply(m_localToParent, *info->m_parentToWorld);

		//
		//--------------------------------------------------------------
		// Check the orientation mode.  The first case is XY orientation
		//--------------------------------------------------------------
		//
		unsigned i;
		if (spec->m_alignZUsingX)
		{
			if (spec->m_alignZUsingY)
			{
				//
				//-----------------------------------------
				// Get the camera location into local space
				//-----------------------------------------
				//
				Stuff::Point3D
					camera_in_world(info->m_clipper->GetCameraToWorldMatrix());
				Stuff::Point3D camera_in_cloud;
				camera_in_cloud.MultiplyByInverse(
					camera_in_world,
					local_to_world
				);
				for (unsigned i = 0; i < m_activeParticleCount; i++)
				{
					Particle *particle = GetParticle(i);
					Check_Object(particle);

					//
					//-----------------------------------------------------------------
					// If the particle is still alive, concatenate into world space and
					// issue the draw command
					//-----------------------------------------------------------------
					//
					if (particle->m_age < 1.0f)
					{
						Stuff::Vector3D direction_in_cloud;
						direction_in_cloud.Subtract(
							camera_in_cloud,
							particle->m_localTranslation
						);
						Stuff::LinearMatrix4D shape_to_cloud;
						shape_to_cloud.BuildRotation(particle->m_localRotation);
						shape_to_cloud.AlignLocalAxisToWorldVector(
							direction_in_cloud,
							Stuff::Z_Axis,
							Stuff::Y_Axis,
							Stuff::X_Axis
						);
						shape_to_cloud.BuildTranslation(particle->m_localTranslation);
						Stuff::LinearMatrix4D shape_to_world;
						shape_to_world.Multiply(
							shape_to_cloud,
							local_to_world
						);
						dinfo.shapeToWorld = &shape_to_world;
						Stuff::Vector3D
							scale(
								particle->m_scale,
								particle->m_scale,
								particle->m_scale
							);
						dinfo.scaling = &scale;
						dinfo.paintMe = &particle->m_color;
		 				info->m_clipper->DrawScalableShape(&dinfo);
						//magic 28112011 begin
						dinfo.shapeToWorld = NULL;
						dinfo.scaling = NULL;
						//magic 28112011 end
					}
				}
			}

			//
			//-----------------------
			// Handle X-only rotation
			//-----------------------
			//
			else
			{
				//
				//-----------------------------------------
				// Get the camera location into local space
				//-----------------------------------------
				//
				Stuff::Point3D
					camera_in_world(info->m_clipper->GetCameraToWorldMatrix());
				Stuff::Point3D camera_in_cloud;
				camera_in_cloud.MultiplyByInverse(
					camera_in_world,
					local_to_world
				);
				for (unsigned i = 0; i < m_activeParticleCount; i++)
				{
					Particle *particle = GetParticle(i);
					Check_Object(particle);

					//
					//-----------------------------------------------------------------
					// If the particle is still alive, concatenate into world space and
					// issue the draw command
					//-----------------------------------------------------------------
					//
					if (particle->m_age < 1.0f)
					{
						Stuff::Vector3D direction_in_cloud;
						direction_in_cloud.Subtract(
							camera_in_cloud,
							particle->m_localTranslation
						);
						Stuff::LinearMatrix4D shape_to_cloud;
						shape_to_cloud.BuildRotation(particle->m_localRotation);
						shape_to_cloud.AlignLocalAxisToWorldVector(
							direction_in_cloud,
							Stuff::Z_Axis,
							Stuff::X_Axis,
							-1
						);
						shape_to_cloud.BuildTranslation(particle->m_localTranslation);
						Stuff::LinearMatrix4D shape_to_world;
						shape_to_world.Multiply(
							shape_to_cloud,
							local_to_world
						);
						dinfo.shapeToWorld = &shape_to_world;
						Stuff::Vector3D
							scale(
								particle->m_scale,
								particle->m_scale,
								particle->m_scale
							);
						dinfo.scaling = &scale;
						dinfo.paintMe = &particle->m_color;
		 				info->m_clipper->DrawScalableShape(&dinfo);
						//magic 28112011 begin
						dinfo.shapeToWorld = NULL;
						dinfo.scaling = NULL;
						//magic 28112011 end
					}
				}
			}
		}

		//
		//-------------------------------------------------------
		// Each matrix needs to be aligned to the camera around Y
		//-------------------------------------------------------
		//
		else if (spec->m_alignZUsingY)
		{
			//
			//-----------------------------------------
			// Get the camera location into local space
			//-----------------------------------------
			//
			Stuff::Point3D
				camera_in_world(info->m_clipper->GetCameraToWorldMatrix());
			Stuff::Point3D camera_in_cloud;
			camera_in_cloud.MultiplyByInverse(
				camera_in_world,
				local_to_world
			);
			for (unsigned i = 0; i < m_activeParticleCount; i++)
			{
				Particle *particle = GetParticle(i);
				Check_Object(particle);

				//
				//-----------------------------------------------------------------
				// If the particle is still alive, concatenate into world space and
				// issue the draw command
				//-----------------------------------------------------------------
				//
				if (particle->m_age < 1.0f)
				{
					Stuff::Vector3D direction_in_cloud;
					direction_in_cloud.Subtract(
						camera_in_cloud,
						particle->m_localTranslation
					);
					Stuff::LinearMatrix4D shape_to_cloud;
					shape_to_cloud.BuildRotation(particle->m_localRotation);
					shape_to_cloud.AlignLocalAxisToWorldVector(
						direction_in_cloud,
						Stuff::Z_Axis,
						Stuff::Y_Axis,
						-1
					);
					shape_to_cloud.BuildTranslation(particle->m_localTranslation);
					Stuff::LinearMatrix4D shape_to_world;
					shape_to_world.Multiply(
						shape_to_cloud,
						local_to_world
					);
					dinfo.shapeToWorld = &shape_to_world;
					Stuff::Vector3D
						scale(
							particle->m_scale,
							particle->m_scale,
							particle->m_scale
						);
					dinfo.scaling = &scale;
					dinfo.paintMe = &particle->m_color;
		 			info->m_clipper->DrawScalableShape(&dinfo);
						//magic 28112011 begin
						dinfo.shapeToWorld = NULL;
						dinfo.scaling = NULL;
						//magic 28112011 end
				}
			}
		}

		//
		//---------------------------------------------------------------
		// No alignment is necessary, so just multiply out all the active
		// particles
		//---------------------------------------------------------------
		//
		else
		{
			for (i=0; i < m_activeParticleCount; i++)
			{
				Particle *particle = GetParticle(i);
				Check_Object(particle);

				//
				//-----------------------------------------------------------------
				// If the particle is still alive, concatenate into world space and
				// issue the draw command
				//-----------------------------------------------------------------
				//
				if (particle->m_age < 1.0f)
				{
					Stuff::LinearMatrix4D shape_to_cloud;
					shape_to_cloud.BuildTranslation(particle->m_localTranslation);
					shape_to_cloud.BuildRotation(particle->m_localRotation);
					Stuff::LinearMatrix4D shape_to_world;
					shape_to_world.Multiply(
						shape_to_cloud,
						local_to_world
					);
					dinfo.shapeToWorld = &shape_to_world;
					Stuff::Vector3D
						scale(
							particle->m_scale,
							particle->m_scale,
							particle->m_scale
						);
					dinfo.scaling = &scale;
					dinfo.paintMe = &particle->m_color;
		 			info->m_clipper->DrawScalableShape(&dinfo);
						//magic 28112011 begin
						dinfo.shapeToWorld = NULL;
						dinfo.scaling = NULL;
						//magic 28112011 end
				}
			}
		}
	}

	//
	//----------------------------
	// Let our parent do its thing
	//----------------------------
	//
	SpinningCloud::Draw(info);
}
示例#30
0
//------------------------------------------------------------------------------
//
bool
gosFX::PointCloud::Execute(ExecuteInfo* info)
{
	Check_Object(this);
	Check_Object(info);
	//
	//----------------------------------------
	// If we aren't supposed to execute, don't
	//----------------------------------------
	//
	if(!IsExecuted())
		return false;
	//
	//------------------------------------------------------------------
	// Animate the particles.  If it is time for us to die, return false
	//------------------------------------------------------------------
	//
	if(!ParticleCloud::Execute(info))
		return false;
	//
	//-----------------------------------------------------------------------
	// If there are active particles to animate, get the current center point
	// of the bounds
	//-----------------------------------------------------------------------
	//
	if(m_activeParticleCount > 0)
	{
		Stuff::ExtentBox box(Stuff::Point3D::Identity, Stuff::Point3D::Identity);
		Stuff::Point3D* vertex = &m_P_localTranslation[0];
		uint32_t i = 0;
		//
		//-------------------------------------------------------------------
		// If there is no bounds yet, we need to create our extent box around
		// the first legal point we find
		//-------------------------------------------------------------------
		//
		while(i < m_activeParticleCount)
		{
			Particle* particle = GetParticle(i);
			Check_Object(particle);
			if(particle->m_age < 1.0f)
			{
				Check_Object(vertex);
				box.maxX = vertex->x;
				box.minX = vertex->x;
				box.maxY = vertex->y;
				box.minY = vertex->y;
				box.maxZ = vertex->z;
				box.minZ = vertex->z;
				++vertex;
				++i;
				break;
			}
			++vertex;
			++i;
		}
		//
		//-----------------------------
		// Look for the other particles
		//-----------------------------
		//
		while(i < m_activeParticleCount)
		{
			Particle* particle = GetParticle(i);
			Check_Object(particle);
			if(particle->m_age < 1.0f)
			{
				Check_Object(vertex);
				if(vertex->x > box.maxX)
					box.maxX = vertex->x;
				else if(vertex->x < box.minX)
					box.minX = vertex->x;
				if(vertex->y > box.maxY)
					box.maxY = vertex->y;
				else if(vertex->y < box.minY)
					box.minY = vertex->y;
				if(vertex->z > box.maxZ)
					box.maxZ = vertex->z;
				else if(vertex->z < box.minZ)
					box.minZ = vertex->z;
			}
			++vertex;
			++i;
		}
		//
		//------------------------------------
		// Now, build a info->m_bounds around this box
		//------------------------------------
		//
		Verify(box.maxX >= box.minX);
		Verify(box.maxY >= box.minY);
		Verify(box.maxZ >= box.minZ);
		Stuff::OBB local_bounds = Stuff::OBB::Identity;
		local_bounds.axisExtents.x = 0.5f * (box.maxX - box.minX);
		local_bounds.axisExtents.y = 0.5f * (box.maxY - box.minY);
		local_bounds.axisExtents.z = 0.5f * (box.maxZ - box.minZ);
		local_bounds.localToParent(3, 0) = box.minX + local_bounds.axisExtents.x;
		local_bounds.localToParent(3, 1) = box.minY + local_bounds.axisExtents.y;
		local_bounds.localToParent(3, 2) = box.minZ + local_bounds.axisExtents.z;
		local_bounds.sphereRadius = local_bounds.axisExtents.GetLength();
		if(local_bounds.sphereRadius < Stuff::SMALL)
			local_bounds.sphereRadius = 0.01f;
		Stuff::OBB parent_bounds;
		parent_bounds.Multiply(local_bounds, m_localToParent);
		info->m_bounds->Union(*info->m_bounds, parent_bounds);
	}
	//
	//----------------------------------------------
	// Tell our caller that we get to keep executing
	//----------------------------------------------
	//
	return true;
}