Exemplo n.º 1
0
// Print what is wrong with the grid, appending it to the existing string
void GridDefinition::PrintError(float originalXrange, float originalYrange, StringRef& r) const
{
	if (spacing < MinSpacing)
	{
		r.cat("Spacing too small");
	}
	else if (numX == 0)
	{
		r.cat("X range too small");
	}
	else if (numY == 0)
	{
		r.cat("Y range too small");
	}
	else if (   numX > MaxXGridPoints
			 || numX > MaxGridProbePoints || numY > MaxGridProbePoints		// check X and Y individually in case X*Y overflows
			 || NumPoints() > MaxGridProbePoints
			)
	{
		const float totalRange = originalXrange + originalYrange;
		const float area = originalXrange * originalYrange;
		const float minSpacing = (totalRange + sqrtf(fsquare(totalRange) + 4.0 * (MaxGridProbePoints - 1) * area))/(2.0 * (MaxGridProbePoints - 1));
		const float minXspacing = originalXrange/(MaxXGridPoints - 1);
		r.catf("Too many grid points; suggest increase spacing to %.1fmm", max<float>(minSpacing, minXspacing));
	}
	else
	{
		// The only thing left is a bad radius
		r.cat("Bad radius");
	}
}
Exemplo n.º 2
0
// Compute Forces - Very slow, but simple. O(n^2)
void FluidSystem::SPH_ComputeForceSlow ()
{
	char *dat1, *dat1_end;
	char *dat2, *dat2_end;
	Fluid *p, *q;
	Vector3DF force, fcurr;
	register double pterm, vterm, dterm;
	double c, r, d, sum, dsq;
	double dx, dy, dz;
	double mR, mR2, visc;

	d = m_Param[SPH_SIMSCALE];
	mR = m_Param[SPH_SMOOTHRADIUS];
	mR2 = (mR*mR);
	visc = m_Param[SPH_VISC];
	vterm = m_LapKern * visc;

	dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
	for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) {
		p = (Fluid*) dat1;

		sum = 0.0;
		force.Set ( 0, 0, 0 );
		
		dat2_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
		for ( dat2 = mBuf[0].data; dat2 < dat2_end; dat2 += mBuf[0].stride ) {
			q = (Fluid*) dat2;

			if ( p == q ) continue;
			dx = ( p->pos.x - q->pos.x )*d;			// dist in cm
			dy = ( p->pos.y - q->pos.y )*d;
			dz = ( p->pos.z - q->pos.z )*d;
			dsq = (dx*dx + dy*dy + dz*dz);
			if ( mR2 > dsq ) {
				r = sqrt ( dsq );
				c = (mR - r);
				pterm = -0.5f * c * m_SpikyKern * ( p->pressure + q->pressure) / r;
				dterm = c * p->density * q->density;
				force.x += ( pterm * dx + vterm * (q->vel_eval.x - p->vel_eval.x) ) * dterm;
				force.y += ( pterm * dy + vterm * (q->vel_eval.y - p->vel_eval.y) ) * dterm;
				force.z += ( pterm * dz + vterm * (q->vel_eval.z - p->vel_eval.z) ) * dterm;
			}
		}			
		p->sph_force = force;		
	}
}
Exemplo n.º 3
0
void PointSet::Grid_InsertParticles ()
{
	char *dat1, *dat1_end;
	Point *p;
	int gs;
	int gx, gy, gz;
	
	dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
	for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) 
		((Point*) dat1)->next = -1;	
//initialize
	for (int n=0; n < m_GridTotal; n++)
	{
		m_Grid[n] = -1;
		m_GridCnt[n] = 0;
		m_GridControlCnt[n] = 0;
	}

	dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
	int n = 0;
	for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) {
		p = (Point*) dat1;
		gx = (int)( (p->pos.x - m_GridMin.x) * m_GridDelta.x);		// Determine grid cell
		gy = (int)( (p->pos.y - m_GridMin.y) * m_GridDelta.y);
		gz = (int)( (p->pos.z - m_GridMin.z) * m_GridDelta.z);
		//grid index gs
		gs = (int)( (gz*m_GridRes.y + gy)*m_GridRes.x + gx);		
		if ( gs >= 0 && gs < m_GridTotal )
		{
			p->next = m_Grid[gs];// pointer to the previous particle in the list of the recent particle
			m_Grid[gs] = n; // stores most recent particle index of that particular cell
			//that particular particle maintains a list of all the previous particles in the cell
			//if(p->type == 0)
			//{
			////m_GridCnt[gs]++; //stores no of particles in one grid cell
			//}
			//
			//if(p->type == 1)
			//{
			//m_GridControlCnt[gs]++; //stores no of particles in one grid cell
			//}

		}
		n++;
	}
}
Exemplo n.º 4
0
int PointSet::AddPointReuse ()
{
	xref ndx;	
	if ( NumPoints() < mBuf[0].max-1 )
		AddElem ( 0, ndx );
	else
		RandomElem ( 0, ndx );
	return ndx;
}
Exemplo n.º 5
0
void PointSet::Advance ()
{
	char* dat;
	Particle* p;
	Vector3DF vnext, accel, norm;

	vnext = m_Vec[EMIT_DANG];
	vnext *= m_DT;
	m_Vec[EMIT_ANG] += vnext;
		
	dat = mBuf[0].data;		
	for ( int c = 0; c < NumPoints(); c++ ) {		
		p = (Particle*) dat;

		accel.Set (0, 0, 0);

		// Plane gravity
		if ( m_Param[PLANE_GRAV] > 0) 
			accel += m_Vec[PLANE_GRAV_DIR];

		// Point gravity
		if ( m_Param[POINT_GRAV] > 0 ) {
			norm.x = ( p->pos.x - m_Vec[POINT_GRAV_POS].x );
			norm.y = ( p->pos.y - m_Vec[POINT_GRAV_POS].y );
			norm.z = ( p->pos.z - m_Vec[POINT_GRAV_POS].z );
			norm.Normalize ();
			norm *= m_Param[POINT_GRAV];
			accel -= norm;
		}
		if(p->type == 0){
		// Leapfrog Integration ----------------------------
		vnext = accel;		
		vnext *= m_DT;
		vnext += p->vel;								// v(t+1/2) = v(t-1/2) + a(t) dt
		p->vel_eval = p->vel;
		p->vel_eval += vnext;
		p->vel_eval *= 0.5;								// v(t+1) = [v(t-1/2) + v(t+1/2)] * 0.5		used to compute forces later
		p->vel = vnext;
		vnext *= m_DT;
		p->pos += vnext;								// p(t+1) = p(t) + v(t+1/2) dt
		}
		// Euler integration -------------------------------
		// accel += m_Gravity;
		// accel *= m_DT;
		// mParticles[c].vel += accel;				// v(t+1) = v(t) + a(t) dt
		// mParticles[c].vel_eval += accel;
		// mParticles[c].vel_eval *= m_DT/d;
		// mParticles[c].pos += mParticles[c].vel_eval;
		// mParticles[c].vel_eval = mParticles[c].vel; 
		
		dat += mBuf[0].stride;
	}

	m_Time += m_DT;
}
Exemplo n.º 6
0
// Compute Pressures - Very slow yet simple. O(n^2)
void FluidSystem::SPH_ComputePressureSlow ()
{
	char *dat1, *dat1_end;
	char *dat2, *dat2_end;
	Fluid *p, *q;
	int cnt = 0;
	double dx, dy, dz, sum, dsq, c;
	double d, d2, mR, mR2;
	d = m_Param[SPH_SIMSCALE];
	d2 = d*d;
	mR = m_Param[SPH_SMOOTHRADIUS];
	mR2 = mR*mR;	

	dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
	for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) {
		p = (Fluid*) dat1;

		sum = 0.0;
		cnt = 0;
		
		dat2_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
		for ( dat2 = mBuf[0].data; dat2 < dat2_end; dat2 += mBuf[0].stride ) {
			q = (Fluid*) dat2;

			if ( p==q ) continue;
			dx = ( p->pos.x - q->pos.x)*d;		// dist in cm
			dy = ( p->pos.y - q->pos.y)*d;
			dz = ( p->pos.z - q->pos.z)*d;
			dsq = (dx*dx + dy*dy + dz*dz);
			if ( mR2 > dsq ) {
				c =  m_R2 - dsq;
				sum += c * c * c;
				cnt++;
				//if ( p == m_CurrP ) q->tag = true;
			}
		}	
		p->density = sum * m_Param[SPH_PMASS] * m_Poly6Kern ;	
		p->pressure = ( p->density - m_Param[SPH_RESTDENSITY] ) * m_Param[SPH_INTSTIFF];
		p->density = 1.0f / p->density;
	}
}
Exemplo n.º 7
0
// Compute Forces - Using spatial grid. Faster.
void FluidSystem::SPH_ComputeForceGrid ()
{
	char *dat1, *dat1_end;	
	Fluid *p;
	Fluid *pcurr;
	int pndx;
	Vector3DF force, fcurr;
	register double pterm, vterm, dterm;
	double c, d, dsq, r;
	double dx, dy, dz;
	double mR, mR2, visc;
	float radius = m_Param[SPH_SMOOTHRADIUS] / m_Param[SPH_SIMSCALE];

	d = m_Param[SPH_SIMSCALE];
	mR = m_Param[SPH_SMOOTHRADIUS];
	mR2 = (mR*mR);
	visc = m_Param[SPH_VISC];

	dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
	for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) {
		p = (Fluid*) dat1;

		force.Set ( 0, 0, 0 );

		Grid_FindCells ( p->pos, radius );
		for (int cell=0; cell < 8; cell++) {
			if ( m_GridCell[cell] != -1 ) {
				pndx = m_Grid [ m_GridCell[cell] ];				
				while ( pndx != -1 ) {					
					pcurr = (Fluid*) (mBuf[0].data + pndx*mBuf[0].stride);					
					if ( pcurr == p ) {pndx = pcurr->next; continue; }
			
					dx = ( p->pos.x - pcurr->pos.x)*d;		// dist in cm
					dy = ( p->pos.y - pcurr->pos.y)*d;
					dz = ( p->pos.z - pcurr->pos.z)*d;
					dsq = (dx*dx + dy*dy + dz*dz);
					if ( mR2 > dsq ) {
						r = sqrt ( dsq );
						c = (mR - r);
						pterm = -0.5f * c * m_SpikyKern * ( p->pressure + pcurr->pressure) / r;
						dterm = c * p->density * pcurr->density;
						vterm =	m_LapKern * visc;
						force.x += ( pterm * dx + vterm * (pcurr->vel_eval.x - p->vel_eval.x) ) * dterm;
						force.y += ( pterm * dy + vterm * (pcurr->vel_eval.y - p->vel_eval.y) ) * dterm;
						force.z += ( pterm * dz + vterm * (pcurr->vel_eval.z - p->vel_eval.z) ) * dterm;
					}
					pndx = pcurr->next;
				}
			}
		}
		p->sph_force = force;
	}
}
Exemplo n.º 8
0
// Compute Pressures - Using spatial grid, and also create neighbor table
void FluidSystem::SPH_ComputePressureGrid ()
{
	char *dat1, *dat1_end;
	Fluid* p;
	Fluid* pcurr;
	int pndx;
	int i, cnt = 0;
	float dx, dy, dz, sum, dsq, c;
	float d, d2, mR, mR2;
	float radius = m_Param[SPH_SMOOTHRADIUS] / m_Param[SPH_SIMSCALE];
	d = m_Param[SPH_SIMSCALE];
	d2 = d*d;
	mR = m_Param[SPH_SMOOTHRADIUS];
	mR2 = mR*mR;	

	dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
	i = 0;
	for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride, i++ ) {
		p = (Fluid*) dat1;

		sum = 0.0;	
		m_NC[i] = 0;

		Grid_FindCells ( p->pos, radius );
		for (int cell=0; cell < 8; cell++) {
			if ( m_GridCell[cell] != -1 ) {
				pndx = m_Grid [ m_GridCell[cell] ];				
				while ( pndx != -1 ) {					
					pcurr = (Fluid*) (mBuf[0].data + pndx*mBuf[0].stride);					
					if ( pcurr == p ) {pndx = pcurr->next; continue; }
					dx = ( p->pos.x - pcurr->pos.x)*d;		// dist in cm
					dy = ( p->pos.y - pcurr->pos.y)*d;
					dz = ( p->pos.z - pcurr->pos.z)*d;
					dsq = (dx*dx + dy*dy + dz*dz);
					if ( mR2 > dsq ) {
						c =  m_R2 - dsq;
						sum += c * c * c;
						if ( m_NC[i] < MAX_NEIGHBOR ) {
							m_Neighbor[i][ m_NC[i] ] = pndx;
							m_NDist[i][ m_NC[i] ] = sqrt(dsq);
							m_NC[i]++;
						}
					}
					pndx = pcurr->next;
				}
			}
			m_GridCell[cell] = -1;
		}
		p->density = sum * m_Param[SPH_PMASS] * m_Poly6Kern ;	
		p->pressure = ( p->density - m_Param[SPH_RESTDENSITY] ) * m_Param[SPH_INTSTIFF];		
		p->density = 1.0f / p->density;		
	}
}
Exemplo n.º 9
0
//----------------------------------------------------------------------------
BOOL DragDropLink::paint(CDC* pDC){
//----------------------------------------------------------------------------
	PROC_TRACE;

   if (!isVisible()) 
       return TRUE;

    if (NumPoints() > 0) {
       inherited::paint(pDC);   
    }

    return TRUE;
}
Exemplo n.º 10
0
Point Polygon::FarthestPointAtAngle(real angle) const
{
    // TODO(mraggi): Replace with Binary search implementation
    int n = NumPoints();

    for (int i = 0; i < n; ++i)
    {
        Point p1 = m_vPoints[i];
        Point p2 = m_vPoints[(i + 1)%n];
        real a1 = p1.Angle();
        real a2 = p2.Angle();

        if (isAngleBetweenAngles(angle, a1, a2))
        {
            Point hola;
            Ray ray(Ray(Point(0, 0), angle));
            ray.Intersects(Segment(p1, p2), hola);
            return hola + Position();
        }
    }
    if (NumPoints() > 2)
        std::cerr << "ERROR IN Polygon::FarthestPointAtAngle" << std::endl;
    return {0, 0};
}
Exemplo n.º 11
0
bool Polygon::Intersects(const Point& other) const
{
    const Polygon& B = *this;
    int n = NumPoints();
    if (n <= 2)
        return false;
    for (int i = 0; i < n; ++i)
    {
        Point X = B[i];
        Point Y = B[(i + 1)%n];

        if (other.IsToTheLeftOfLine(X, Y) || X == Y)
            return false;
    }
    return true;
}
Exemplo n.º 12
0
Point Polygon::ClosestPoint(const Point& point) const
{
    if (Intersects(point))
        return point;

    Point closestSoFar = GetPoint(0);

    for (int i = 0; i < NumPoints(); ++i)
    {
        Segment seg(GetPoint(i), GetPoint(i + 1));
        Point closestNow = seg.ClosestPoint(point);
        if (point.IsCloserToFirstThanSecond(closestNow, closestSoFar))
            closestSoFar = closestNow;
    }

    return closestSoFar;
}
Exemplo n.º 13
0
int FluidSystem::AddPointReuse ()
{
	xref ndx;	
	Fluid* f;
	if ( NumPoints() <= mBuf[0].max-2 )
		f = (Fluid*) AddElem ( 0, ndx );
	else
		f = (Fluid*) RandomElem ( 0, ndx );

	f->sph_force.Set(0,0,0);
	f->vel.Set(0,0,0);
	f->vel_eval.Set(0,0,0);
	f->next = 0x0;
	f->pressure = 0;
	f->density = 0;
	return ndx;
}
Exemplo n.º 14
0
// Compute Forces - Using spatial grid with saved neighbor table. Fastest.
void FluidSystem::SPH_ComputeForceGridNC ()
{
	char *dat1, *dat1_end;	
	Fluid *p;
	Fluid *pcurr;
	Vector3DF force, fcurr;
	register float pterm, vterm, dterm;
	int i;
	float c, d;
	float dx, dy, dz;
	float mR, mR2, visc;	

	d = m_Param[SPH_SIMSCALE];
	mR = m_Param[SPH_SMOOTHRADIUS];
	mR2 = (mR*mR);
	visc = m_Param[SPH_VISC];

	dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
	i = 0;
	
	for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride, i++ ) {
		p = (Fluid*) dat1;

		force.Set ( 0, 0, 0 );
		for (int j=0; j < m_NC[i]; j++ ) {
			pcurr = (Fluid*) (mBuf[0].data + m_Neighbor[i][j]*mBuf[0].stride);
			dx = ( p->pos.x - pcurr->pos.x)*d;		// dist in cm
			dy = ( p->pos.y - pcurr->pos.y)*d;
			dz = ( p->pos.z - pcurr->pos.z)*d;				
			c = ( mR - m_NDist[i][j] );
			pterm = -0.5f * c * m_SpikyKern * ( p->pressure + pcurr->pressure) / m_NDist[i][j];
			dterm = c * p->density * pcurr->density;
			vterm = m_LapKern * visc;
			force.x += ( pterm * dx + vterm * (pcurr->vel_eval.x - p->vel_eval.x) ) * dterm;
			force.y += ( pterm * dy + vterm * (pcurr->vel_eval.y - p->vel_eval.y) ) * dterm;
			force.z += ( pterm * dz + vterm * (pcurr->vel_eval.z - p->vel_eval.z) ) * dterm;
		}			
		p->sph_force = force;
	}
}
Exemplo n.º 15
0
//----------------------------------------------------------------------------
void DragDropLink::GainedSelection(DragDropSelection* pSelection){
//----------------------------------------------------------------------------
	PROC_TRACE;


   assert(pSelection!=NULL);
   // the link has gained selection, it is time to set up resize handles
    
   if (!IsResizable()) {
       pSelection->CreateBoundingHandle (this);    
       return;
   }
       
    
   CPoint point;
   for (int i=1; i < NumPoints()-1; i++){
       point = GetPoint(i);
       pSelection->CreateResizeHandle (this, point.x, point.y, i + HandlesLast, TRUE);
   }           
    
    return;
                                                           
} 
Exemplo n.º 16
0
// Append the grid parameters to the end of a string
void GridDefinition::PrintParameters(StringRef& s) const
{
	s.catf("X%.1f:%.1f, Y%.1f:%.1f, radius %.1f, spacing %.1f, %d points", xMin, xMax, yMin, yMax, radius, spacing, NumPoints());
}
Exemplo n.º 17
0
//----------------------------------------------------------------------------
int DragDropLink::GetLastPickPoint(){
//----------------------------------------------------------------------------
	PROC_TRACE;

   return NumPoints()-1;
}
Exemplo n.º 18
0
Point Polygon::GetPoint(int index) const
{
    return Position() + m_vPoints[index%NumPoints()];
}
Exemplo n.º 19
0
void GridDefinition::CheckValidity()
{
	isValid = NumPoints() != 0 && NumPoints() <= MaxGridProbePoints
			&& (radius < 0.0 || radius >= 1.0)
			&& NumXpoints() <= MaxXGridPoints;
}
Exemplo n.º 20
0
		void SetPoint(unsigned int i, const float3& p) { points[std::min(i, NumPoints() - 1)] = p; }
Exemplo n.º 21
0
void FluidSystem::SPH_CreateExample ( int n, int nmax )
{
	Vector3DF pos;
	Vector3DF min, max;
	
	Reset ( nmax );
	
	switch ( n ) {
	case 0:		// Wave pool
				
		//-- TEST CASE: 2x2x2 grid, 32 particles.  NOTE: Set PRADIUS to 0.0004 to reduce wall influence
		//     grid 0:    3*3*2 = 18 particles
		//     grid 1,2:  3*1*2 =  6 particles
		//     grid 3:    1*1*2 =  2 particles
		//     grid 4,5,6:    0 =  0 particles
		/*m_Vec [ SPH_VOLMIN ].Set ( -2.5, -2.5, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 2.5, 2.5, 5.0 );	
		m_Vec [ SPH_INITMIN ].Set ( -2.5, -2.5, 0 );	
		m_Vec [ SPH_INITMAX ].Set ( 2.5, 2.5, 1.6 );*/  
		
		m_Vec [ SPH_VOLMIN ].Set ( -30, -30, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 30, 30, 40 );		

		//m_Vec [ SPH_INITMIN ].Set ( -5, -5, 10 );
		//m_Vec [ SPH_INITMAX ].Set ( 5, 5, 20 );
		
		m_Vec [ SPH_INITMIN ].Set ( -20, -26, 10 );
		m_Vec [ SPH_INITMAX ].Set ( 20, 26, 40 );

		m_Param [ FORCE_XMIN_SIN ] = 12.0;
		m_Param [ BOUND_ZMIN_SLOPE ] = 0.05;
		break;
	case 1:		// Dam break
		m_Vec [ SPH_VOLMIN ].Set ( -30, -14, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 30, 14, 60 );
		m_Vec [ SPH_INITMIN ].Set ( 0, -13, 0 );
		m_Vec [ SPH_INITMAX ].Set ( 29, 13, 30 );		
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
		break;
	case 2:		// Dual-Wave pool
		m_Vec [ SPH_VOLMIN ].Set ( -60, -5, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 60, 5, 50 );
		m_Vec [ SPH_INITMIN ].Set ( -46, -5, 0 );
		m_Vec [ SPH_INITMAX ].Set ( 46, 5, 15 );
		m_Param [ FORCE_XMIN_SIN ] = 8.0;
		m_Param [ FORCE_XMAX_SIN ] = 8.0;
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
		break;
	case 3:		// Swirl Stream
		m_Vec [ SPH_VOLMIN ].Set ( -30, -30, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 30, 30, 50 );
		m_Vec [ SPH_INITMIN ].Set ( -30, -30, 0 );
		m_Vec [ SPH_INITMAX ].Set ( 30, 30, 40 );
		m_Vec [ EMIT_POS ].Set ( -20, -20, 22 );
		m_Vec [ EMIT_RATE ].Set ( 1, 4, 0 );
		m_Vec [ EMIT_ANG ].Set ( 0, 120, 1.5 );
		m_Vec [ EMIT_DANG ].Set ( 0, 0, 0 );
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
		break;
	case 4:		// Shockwave
		m_Vec [ SPH_VOLMIN ].Set ( -60, -15, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 60, 15, 50 );
		m_Vec [ SPH_INITMIN ].Set ( -59, -14, 0 );
		m_Vec [ SPH_INITMAX ].Set ( 59, 14, 30 );
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
		m_Toggle [ WALL_BARRIER ] = true;
		m_Toggle [ WRAP_X ] = true;
		break;
	case 5:		// Zero gravity
		m_Vec [ SPH_VOLMIN ].Set ( -40, -40, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 40, 40, 50 );
		m_Vec [ SPH_INITMIN ].Set ( -20, -20, 20 );
		m_Vec [ SPH_INITMAX ].Set ( 20, 20, 40 );
		m_Vec [ EMIT_POS ].Set ( -20, 0, 40 );
		m_Vec [ EMIT_RATE ].Set ( 2, 1, 0 );		
		m_Vec [ EMIT_ANG ].Set ( 0, 120, 0.25 );
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0, 0, 0 );
		m_Param [ SPH_INTSTIFF ] = 0.20;		
		break;
	case 6:		// Point gravity		
		m_Vec [ SPH_VOLMIN ].Set ( -40, -40, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 40, 40, 50 );
		m_Vec [ SPH_INITMIN ].Set ( -20, -20, 20 );
		m_Vec [ SPH_INITMAX ].Set ( 20, 20, 40 );
		m_Param [ SPH_INTSTIFF ] = 0.50;		
		m_Vec [ EMIT_POS ].Set ( -20, 20, 25 );
		m_Vec [ EMIT_RATE ].Set ( 1, 4, 0 );		
		m_Vec [ EMIT_ANG ].Set ( -20, 100, 2.0 );
		m_Vec [ POINT_GRAV_POS ].Set ( 0, 0, 25 );
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0, 0, 0 );
		m_Param [ POINT_GRAV ] = 3.5;
		break;
	case 7:		// Levy break
		m_Vec [ SPH_VOLMIN ].Set ( -40, -40, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 40, 40, 50 );
		m_Vec [ SPH_INITMIN ].Set ( 10, -40, 0 );
		m_Vec [ SPH_INITMAX ].Set ( 40, 40, 50 );
		m_Vec [ EMIT_POS ].Set ( 34, 27, 16.6 );
		m_Vec [ EMIT_RATE ].Set ( 2, 9, 0 );		
		m_Vec [ EMIT_ANG ].Set ( 118, 200, 1.0 );
		m_Toggle [ LEVY_BARRIER ] = true;
		m_Param [ BOUND_ZMIN_SLOPE ] = 0.1;
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
		break;
	case 8:		// Drain
		m_Vec [ SPH_VOLMIN ].Set ( -20, -20, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 20, 20, 50 );
		m_Vec [ SPH_INITMIN ].Set ( -15, -20, 20 );
		m_Vec [ SPH_INITMAX ].Set ( 20, 20, 50 );
		m_Vec [ EMIT_POS ].Set ( -16, -16, 30 );
		m_Vec [ EMIT_RATE ].Set ( 1, 4, 0 );		
		m_Vec [ EMIT_ANG ].Set ( -20, 140, 1.8 );
		m_Toggle [ DRAIN_BARRIER ] = true;
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
		break;
	case 9:			// Tumbler
		m_Vec [ SPH_VOLMIN ].Set ( -30, -30, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 30, 30, 50 );
		m_Vec [ SPH_INITMIN ].Set ( 24, -29, 20 );
		m_Vec [ SPH_INITMAX ].Set ( 29, 29, 40 );
		m_Param [ SPH_VISC ] = 0.1;		
		m_Param [ SPH_INTSTIFF ] = 0.50;
		m_Param [ SPH_EXTSTIFF ] = 8000;
		//m_Param [ SPH_SMOOTHRADIUS ] = 0.01;
		m_Param [ BOUND_ZMIN_SLOPE ] = 0.4;
		m_Param [ FORCE_XMIN_SIN ] = 12.00;
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
		break;	
	case 10:		// Large sim
		m_Vec [ SPH_VOLMIN ].Set ( -35, -35, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 35, 35, 60 );
		m_Vec [ SPH_INITMIN ].Set ( -5, -35, 0 );
		m_Vec [ SPH_INITMAX ].Set ( 30, 0, 60 );
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
		break;
	}	

	SPH_ComputeKernels ();

	m_Param [ SPH_SIMSIZE ] = m_Param [ SPH_SIMSCALE ] * (m_Vec[SPH_VOLMAX].z - m_Vec[SPH_VOLMIN].z);
	m_Param [ SPH_PDIST ] = pow ( m_Param[SPH_PMASS] / m_Param[SPH_RESTDENSITY], 1/3.0 );	

	float ss = m_Param [ SPH_PDIST ]*0.87 / m_Param[ SPH_SIMSCALE ];	
	printf ( "Spacing: %f\n", ss);
	AddVolume ( m_Vec[SPH_INITMIN], m_Vec[SPH_INITMAX], ss );	// Create the particles

	float cell_size = m_Param[SPH_SMOOTHRADIUS]*2.0;			// Grid cell size (2r)	
	Grid_Setup ( m_Vec[SPH_VOLMIN], m_Vec[SPH_VOLMAX], m_Param[SPH_SIMSCALE], cell_size, 1.0 );												// Setup grid
	Grid_InsertParticles ();									// Insert particles

	Vector3DF vmin, vmax;
	vmin =  m_Vec[SPH_VOLMIN];
	vmin -= Vector3DF(2,2,2);
	vmax =  m_Vec[SPH_VOLMAX];
	vmax += Vector3DF(2,2,-2);

	#ifdef BUILD_CUDA
		FluidClearCUDA ();
		Sleep ( 500 );

		FluidSetupCUDA ( NumPoints(), sizeof(Fluid), *(float3*)& m_GridMin, *(float3*)& m_GridMax, *(float3*)& m_GridRes, *(float3*)& m_GridSize, (int) m_Vec[EMIT_RATE].x );

		Sleep ( 500 );

		FluidParamCUDA ( m_Param[SPH_SIMSCALE], m_Param[SPH_SMOOTHRADIUS], m_Param[SPH_PMASS], m_Param[SPH_RESTDENSITY], m_Param[SPH_INTSTIFF], m_Param[SPH_VISC] );
	#endif

}
Exemplo n.º 22
0
void FluidSystem::Advance ()
{
	char *dat1, *dat1_end;
	Fluid* p;
	Vector3DF norm, z;
	Vector3DF dir, accel;
	Vector3DF vnext;
	Vector3DF min, max;
	double adj;
	float SL, SL2, ss, radius;
	float stiff, damp, speed, diff; 
	SL = m_Param[SPH_LIMIT];
	SL2 = SL*SL;
	
	stiff = m_Param[SPH_EXTSTIFF];
	damp = m_Param[SPH_EXTDAMP];
	radius = m_Param[SPH_PRADIUS];
	min = m_Vec[SPH_VOLMIN];
	max = m_Vec[SPH_VOLMAX];
	ss = m_Param[SPH_SIMSCALE];

	dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
	for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) {
		p = (Fluid*) dat1;		

		// Compute Acceleration		
		accel = p->sph_force;
		accel *= m_Param[SPH_PMASS];

		// Velocity limiting 
		speed = accel.x*accel.x + accel.y*accel.y + accel.z*accel.z;
		if ( speed > SL2 ) {
			accel *= SL / sqrt(speed);
		}		
	
		// Boundary Conditions

		// Z-axis walls
		diff = 2 * radius - ( p->pos.z - min.z - (p->pos.x - m_Vec[SPH_VOLMIN].x) * m_Param[BOUND_ZMIN_SLOPE] )*ss;
		if (diff > EPSILON ) {			
			norm.Set ( -m_Param[BOUND_ZMIN_SLOPE], 0, 1.0 - m_Param[BOUND_ZMIN_SLOPE] );
			adj = stiff * diff - damp * norm.Dot ( p->vel_eval );
			accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;
		}		

		diff = 2 * radius - ( max.z - p->pos.z )*ss;
		if (diff > EPSILON) {
			norm.Set ( 0, 0, -1 );
			adj = stiff * diff - damp * norm.Dot ( p->vel_eval );
			accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;
		}
		
		// X-axis walls
		if ( !m_Toggle[WRAP_X] ) {
			diff = 2 * radius - ( p->pos.x - min.x + (sin(m_Time*10.0)-1+(p->pos.y*0.025)*0.25) * m_Param[FORCE_XMIN_SIN] )*ss;	
			//diff = 2 * radius - ( p->pos.x - min.x + (sin(m_Time*10.0)-1) * m_Param[FORCE_XMIN_SIN] )*ss;	
			if (diff > EPSILON ) {
				norm.Set ( 1.0, 0, 0 );
				adj = (m_Param[ FORCE_XMIN_SIN ] + 1) * stiff * diff - damp * norm.Dot ( p->vel_eval ) ;
				accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;					
			}

			diff = 2 * radius - ( max.x - p->pos.x + (sin(m_Time*10.0)-1) * m_Param[FORCE_XMAX_SIN] )*ss;	
			if (diff > EPSILON) {
				norm.Set ( -1, 0, 0 );
				adj = (m_Param[ FORCE_XMAX_SIN ]+1) * stiff * diff - damp * norm.Dot ( p->vel_eval );
				accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;
			}
		}

		// Y-axis walls
		diff = 2 * radius - ( p->pos.y - min.y )*ss;			
		if (diff > EPSILON) {
			norm.Set ( 0, 1, 0 );
			adj = stiff * diff - damp * norm.Dot ( p->vel_eval );
			accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;
		}
		diff = 2 * radius - ( max.y - p->pos.y )*ss;
		if (diff > EPSILON) {
			norm.Set ( 0, -1, 0 );
			adj = stiff * diff - damp * norm.Dot ( p->vel_eval );
			accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;
		}

		// Wall barrier
		if ( m_Toggle[WALL_BARRIER] ) {
			diff = 2 * radius - ( p->pos.x - 0 )*ss;					
			if (diff < 2*radius && diff > EPSILON && fabs(p->pos.y) < 3 && p->pos.z < 10) {
				norm.Set ( 1.0, 0, 0 );
				adj = 2*stiff * diff - damp * norm.Dot ( p->vel_eval ) ;	
				accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;					
			}
		}
		
		// Levy barrier
		if ( m_Toggle[LEVY_BARRIER] ) {
			diff = 2 * radius - ( p->pos.x - 0 )*ss;					
			if (diff < 2*radius && diff > EPSILON && fabs(p->pos.y) > 5 && p->pos.z < 10) {
				norm.Set ( 1.0, 0, 0 );
				adj = 2*stiff * diff - damp * norm.Dot ( p->vel_eval ) ;	
				accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;					
			}
		}
		// Drain barrier
		if ( m_Toggle[DRAIN_BARRIER] ) {
			diff = 2 * radius - ( p->pos.z - min.z-15 )*ss;
			if (diff < 2*radius && diff > EPSILON && (fabs(p->pos.x)>3 || fabs(p->pos.y)>3) ) {
				norm.Set ( 0, 0, 1);
				adj = stiff * diff - damp * norm.Dot ( p->vel_eval );
				accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;
			}
		}

		// Plane gravity
		if ( m_Param[PLANE_GRAV] > 0) 
			accel += m_Vec[PLANE_GRAV_DIR];

		// Point gravity
		if ( m_Param[POINT_GRAV] > 0 ) {
			norm.x = ( p->pos.x - m_Vec[POINT_GRAV_POS].x );
			norm.y = ( p->pos.y - m_Vec[POINT_GRAV_POS].y );
			norm.z = ( p->pos.z - m_Vec[POINT_GRAV_POS].z );
			norm.Normalize ();
			norm *= m_Param[POINT_GRAV];
			accel -= norm;
		}

		// Leapfrog Integration ----------------------------
		vnext = accel;							
		vnext *= m_DT;
		vnext += p->vel;						// v(t+1/2) = v(t-1/2) + a(t) dt
		p->vel_eval = p->vel;
		p->vel_eval += vnext;
		p->vel_eval *= 0.5;					// v(t+1) = [v(t-1/2) + v(t+1/2)] * 0.5		used to compute forces later
		p->vel = vnext;
		vnext *= m_DT/ss;
		p->pos += vnext;						// p(t+1) = p(t) + v(t+1/2) dt

		if ( m_Param[CLR_MODE]==1.0 ) {
			adj = fabs(vnext.x)+fabs(vnext.y)+fabs(vnext.z) / 7000.0;
			adj = (adj > 1.0) ? 1.0 : adj;
			p->clr = COLORA( 0, adj, adj, 1 );
		}
		if ( m_Param[CLR_MODE]==2.0 ) {
			float v = 0.5 + ( p->pressure / 1500.0); 
			if ( v < 0.1 ) v = 0.1;
			if ( v > 1.0 ) v = 1.0;
			p->clr = COLORA ( v, 1-v, 0, 1 );
		}


		// Euler integration -------------------------------
		/* accel += m_Gravity;
		accel *= m_DT;
		p->vel += accel;				// v(t+1) = v(t) + a(t) dt
		p->vel_eval += accel;
		p->vel_eval *= m_DT/d;
		p->pos += p->vel_eval;
		p->vel_eval = p->vel;  */	


		if ( m_Toggle[WRAP_X] ) {
			diff = p->pos.x - (m_Vec[SPH_VOLMIN].x + 2);			// -- Simulates object in center of flow
			if ( diff <= 0 ) {
				p->pos.x = (m_Vec[SPH_VOLMAX].x - 2) + diff*2;				
				p->pos.z = 10;
			}
		}	
	}

	m_Time += m_DT;
}
Exemplo n.º 23
0
void FluidSystem::Run ()
{
	bool bTiming = true;

	mint::Time start, stop;
	
	float ss = m_Param [ SPH_PDIST ] / m_Param[ SPH_SIMSCALE ];		// simulation scale (not Schutzstaffel)

	if ( m_Vec[EMIT_RATE].x > 0 && (++m_Frame) % (int) m_Vec[EMIT_RATE].x == 0 ) {
		//m_Frame = 0;
		Emit ( ss ); 
	}
	
	#ifdef NOGRID
		// Slow method - O(n^2)
		SPH_ComputePressureSlow ();
		SPH_ComputeForceSlow ();
	#else

		if ( m_Toggle[USE_CUDA] ) {
			
			#ifdef BUILD_CUDA
				// -- GPU --
				start.SetSystemTime ( ACC_NSEC );		
				TransferToCUDA ( mBuf[0].data, (int*) &m_Grid[0], NumPoints() );
				if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "TO: %s\n", stop.GetReadableTime().c_str() ); }
			
				start.SetSystemTime ( ACC_NSEC );		
				Grid_InsertParticlesCUDA ();
				if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "INSERT (CUDA): %s\n", stop.GetReadableTime().c_str() ); }

				start.SetSystemTime ( ACC_NSEC );
				SPH_ComputePressureCUDA ();
				if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "PRESS (CUDA): %s\n", stop.GetReadableTime().c_str() ); }

				start.SetSystemTime ( ACC_NSEC );
				SPH_ComputeForceCUDA (); 
				if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "FORCE (CUDA): %s\n", stop.GetReadableTime().c_str() ); }

				//** CUDA integrator is incomplete..
				// Once integrator is done, we can remove TransferTo/From steps
				/*start.SetSystemTime ( ACC_NSEC );
				SPH_AdvanceCUDA( m_DT, m_DT/m_Param[SPH_SIMSCALE] );
				if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "ADV (CUDA): %s\n", stop.GetReadableTime().c_str() ); }*/

				start.SetSystemTime ( ACC_NSEC );		
				TransferFromCUDA ( mBuf[0].data, (int*) &m_Grid[0], NumPoints() );
				if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "FROM: %s\n", stop.GetReadableTime().c_str() ); }

				// .. Do advance on CPU 
				Advance();

			#endif
			
		} else {
			// -- CPU only --

			start.SetSystemTime ( ACC_NSEC );
			Grid_InsertParticles ();
			if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "INSERT: %s\n", stop.GetReadableTime().c_str() ); }
		
			start.SetSystemTime ( ACC_NSEC );
			SPH_ComputePressureGrid ();
			if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "PRESS: %s\n", stop.GetReadableTime().c_str() ); }

			start.SetSystemTime ( ACC_NSEC );
			SPH_ComputeForceGridNC ();		
			if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "FORCE: %s\n", stop.GetReadableTime().c_str() ); }

			start.SetSystemTime ( ACC_NSEC );
			Advance();
			if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "ADV: %s\n", stop.GetReadableTime().c_str() ); }
		}		
		
	#endif
}
Exemplo n.º 24
0
		const float3& GetPoint(unsigned int i) const { return points[std::min(i, NumPoints() - 1)]; }
Exemplo n.º 25
0
void TriObject::Deform(Deformer *defProc,int useSel) {
	int nv = NumPoints();
	int i;
	if ( useSel ) {
		BitArray sel = mesh.VertexTempSel();
		float *vssel = mesh.getVSelectionWeights ();
#if TRI_MULTI_PROCESSING
		WaitForSingleObject(defMutex, INFINITE);
		defStuff.triobj = this;
		defStuff.defProc = defProc;
		defStuff.ct = nv / 2;
		defStuff.useSel = 1;
		defStuff.sel = sel;
		defStuff.vssel = vssel;
		SetEvent(defStartEvent);
		Sleep(0);
		if (vssel) {
			for (i=nv/2; i<nv; i++) {
				if(sel[i]) {
					SetPoint(i,defProc->Map(i,GetPoint(i)));
					continue;
				}
				if (vssel[i]==0) continue;
				Point3 & A = GetPoint(i);
				Point3 dir = defProc->Map(i,A) - A;
				SetPoint(i,A+vssel[i]*dir);
			}
		} else {
			for (i=nv/2; i<nv; i++) if(sel[i]) SetPoint(i,defProc->Map(i,GetPoint(i)));
		}
		WaitForSingleObject(defEndEvent, INFINITE);
		ReleaseMutex(defMutex);
#else
		if (vssel) {
			for (i=0; i<nv; i++) {
				if(sel[i]) {
					SetPoint(i,defProc->Map(i,GetPoint(i)));
					continue;
				}
				if (vssel[i]==0) continue;
				Point3 & A = GetPoint(i);
				Point3 dir = defProc->Map(i,A) - A;
				SetPoint(i,A+vssel[i]*dir);
			}
		} else {
			for (i=0; i<nv; i++) if (sel[i]) SetPoint(i,defProc->Map(i,GetPoint(i)));
		}
#endif
	} else {
#if TRI_MULTI_PROCESSING
		WaitForSingleObject(defMutex, INFINITE);
		defStuff.triobj = this;
		defStuff.defProc = defProc;
		defStuff.ct = nv / 2;
		defStuff.useSel = 0;
		SetEvent(defStartEvent);
		Sleep(0);
		for (i=nv/2; i<nv; i++) 
			SetPoint(i,defProc->Map(i,GetPoint(i)));
		WaitForSingleObject(defEndEvent, INFINITE);
		ReleaseMutex(defMutex);
#else
		for (i=0; i<nv; i++) 
			SetPoint(i,defProc->Map(i,GetPoint(i)));
#endif
	}
	PointsWereChanged();
}