Esempio n. 1
0
Bond::Bond(int d0, int d1, DEMsystem &dem_){
    cerr << "!!!" << endl;
    dem = &dem_;
	status = 1;
    initial_bond = dem->initialprocess;
	bond_number = dem->n_bond;
	dem->n_bond ++ ;
	d[0] = d0, d[1] = d1;  
	dem->ct->on_connect( d[0], d[1] );
	p_particle0 = dem->particle[d[0]];
	p_particle1 = dem->particle[d[1]];

	(*p_particle1).setBond(bond_number, d[0]);
	(*p_particle0).setBond(bond_number, d[1]);
	
    pp[0] = (*p_particle0).p_pos(); // pointer to postion of particle 0.
	pu[0] = (*p_particle0).pu_back(); // pointer to u vector of particle 0.

    pp[1] = (*p_particle1).p_pos();
	pu[1] = (*p_particle1).pu_back();

    r_vec = (*pp[1]) - (*pp[0]);

	p_tor[0] = (*p_particle0).p_tor_angle_back();
    p_tor[1] = (*p_particle1).p_tor_angle_back();
	(*p_tor[0]) = 0;
	(*p_tor[1]) = 0;

	r = r_vec.norm();
	e_normal = r_vec / r;

	(*pu[0]) = e_normal;
	(*pu[1]) = - e_normal;
    
    u_vector[0] = (*p_particle0).orientation.ori_backward(*pu[0]);
    u_vector[1] = (*p_particle1).orientation.ori_backward(*pu[1]);

    if (initial_bond){
        u_vector_initial[0] = u_vector[0];
        u_vector_initial[1] = u_vector[1];
    }

    if (initial_bond)
        para = dem->bond0;
    else
        para = dem->bond1;
    
    
    sq_fsc = sq(para.fsc);
    sq_mbc = sq(para.mbc);
    sq_mtc = sq(para.mtc);
    
    calcForce();
}
Esempio n. 2
0
void Bond::regeneration(){
    status = 2;
	r_vec = (*pp[1]) - (*pp[0]);
    r = r_vec.norm();
	e_normal = r_vec/r;
    (*pu[0]) = e_normal;
	(*pu[1]) = - e_normal;
    (*p_tor[0]) = 0.0;
	(*p_tor[1]) = 0.0;
    u_vector[0] = (*p_particle0).orientation.ori_backward(*pu[0]);
    u_vector[1] = (*p_particle1).orientation.ori_backward(*pu[1]);

    calcForce();
	//regeneration_tuzuku = true;
}
void PotentialPlanner2::calcTotalForce() 
{
	Vector2D temp_force;
	setVector2D(temp_force,0.0,0.0);
	for (int i=0;i<pedestrians->size();++i)
	{
		temp_force = addVector2D(temp_force, calcForce( *((*pedestrians)[i]) ));
	}
	//ADD THE GOAL EFFECT
	temp_force.y += 70.0*m_charge;

	//ADD THE ROAD EFFECT
	dd isInside = 1.0;
	dd dx_left = car->getX()-PAVEMENT_LEFT_X_MAX-car->getWidth()/2;
	dd dx_right = car->getX()-PAVEMENT_RIGHT_X_MIN+car->getWidth()/2;
	if (!(car->getX()-car->getWidth()/2 > PAVEMENT_LEFT_X_MAX && car->getX()+car->getWidth()/2 < PAVEMENT_RIGHT_X_MIN)) isInside=-1.0;
	temp_force.x += (10.0*10.0)*isInside*m_charge*abs(car->getV()*cos(car->getTheta()))/(dx_left*dx_left*dx_left);
	temp_force.x += (10.0*10.0)*isInside*m_charge*abs(car->getV()*cos(car->getTheta()))/(dx_right*dx_right*dx_right);
	
	//We use temp_force first to let the GUI only drawing the resultant force	
	m_force = temp_force;
}
Esempio n. 4
0
// Physics thread that controls the motion of all the spheres.
void physicsThread(int threadNum)
{
	int localFrame = 0;

	// Define the normals for each of the walls.
	static const Vector3 bottom(0, 1, 0);
	static const Vector3 left(1, 0, 0);
	static const Vector3 right(-1, 0, 0);
	static const Vector3 front(0, 0, -1);
	static const Vector3 back(0, 0, 1);

	// Initialize the starting values for the wall and sphere, spring and damping values.
	float wallSpringConst = UPPER_WALL_SPRING_CONST;
	float sphereSpringConst = UPPER_SPHERE_SPRING_CONST;

	float wallDampFactor = UPPER_WALL_DAMP_FACTOR;
	float sphereDampFactor = UPPER_SPHERE_DAMP_FACTOR;

	// The physics thread itself deals with reseting its frame counter. 
	// It will do this once a second.
	float secondCheck = 0.0f;

#if _USE_MT
	// If the physics function is being called as a thread, then we don't want it 
	// to finish after one pass.
	int threadRunning = 0;
	while(programRunning)
	{
		// If the simulation needs to be paused but the thread is running,
		// stop.
		if(pauseSimulation && threadRunning)
		{
			threadRunning = 0;
			threadStopped();
		}
		// If the simulation needs to be running but the thread is stopped,
		// start.
		else if(!pauseSimulation && !threadRunning)
		{
			threadRunning = 1;
			threadStarted();
		}

		// If the thread isn't running at this time we can't go any further and 
		// we'll just wait and check if the thread has started up next time the
		// thread is executing.
		if(!threadRunning)
		{
			boost::this_thread::yield();
			continue;
		}
#endif

		localFrame++;

		LARGE_INTEGER time;
		QueryPerformanceCounter(&time);

		// Get the time since this thread last executed and convert into
		// seconds (from milliseconds).
		float dt = (float)(((double)time.QuadPart - (double)updateTimes[threadNum].QuadPart) / freq);
		dt *= 0.001;

		// Adjust the spring and dampening values based on dt.
		// This helps when going to lower frame rates and the overlap between
		// the walls and spheres when using high frame rate values will cause
		// the spheres to gain energy.
		wallSpringConst = WALL_SPRING_GRAD * dt + WALL_SPRING_CONST;
		sphereSpringConst = SPHERE_SPRING_GRAD * dt + SPHERE_SPRING_CONST;

		wallDampFactor = WALL_DAMP_GRAD * dt + WALL_DAMP_CONST;
		sphereDampFactor = SPHERE_DAMP_GRAD * dt + SPHERE_DAMP_CONST;

		// As the gradients for the spring and dampening factors are negative,
		// we want to clamp the lower bounds of the values. Otherwise at low
		// framerates the values will be negative.
		if (wallSpringConst < LOWER_WALL_SPRING_CONST)
			wallSpringConst = LOWER_WALL_SPRING_CONST;

		if (sphereSpringConst < LOWER_SPHERE_SPRING_CONST)
			sphereSpringConst = LOWER_SPHERE_SPRING_CONST;

		if (wallDampFactor < LOWER_WALL_DAMP_FACTOR)
			wallDampFactor = LOWER_WALL_DAMP_FACTOR;

		if (sphereDampFactor < LOWER_SPHERE_DAMP_FACTOR)
			sphereDampFactor = LOWER_SPHERE_DAMP_FACTOR;

		// If this is the 1st thread, then we will deal with the user controlled
		// sphere here.
		int startSphere = threadNum;
		if(threadNum == 0)
		{
			// Skip calcuating the user sphere like a typical sphere.
			startSphere += numPhysicsThreads;

			// As the user controlled sphere only has a position and velocity
			// that is either zero or constant, we can easily calculate its new
			// position.
			if(numSpheres > 0)
			{
				spherePositions[0] += sphereData[0].m_velocity * dt;
			}
		}

		for(int i = startSphere; i < numSpheres; i += numPhysicsThreads)
		{
			// Calculate the radius of the sphere based on array index.
			float radius = (float)((i % 3) + 1) * 0.5f;
			float roomSize = ROOM_SIZE - radius;
			
			Vector3 forces(0);

			Vector3 &spherePosition = spherePositions[i];
			SphereData &sphere = sphereData[i];

			// Calculate the interim velocity.
			Vector3 halfVelo = sphere.m_velocity + (0.5f * sphere.m_acc * dt);
			spherePosition += halfVelo * dt;

			Vector3 tempVelocity = sphere.m_velocity + (sphere.m_acc * dt);

			float overlap;

			// As the % operator is fairly slow we can take advantage here
			// that we always know what the next value in the array is going
			// to be and manually determine the mod.
			int indexCounter = 0;
			
			for(int j = 0; j < numSpheres; j++)
			{
				// And since we don't want the actual mod value but mod + 1
				// we don't worry about resetting to 0.
				indexCounter++;
				if(indexCounter > 3)
					indexCounter = 1;

				// We don't want a sphere to check if it's collided with itself.
				if(i == j)
					continue;

				SphereData &otherSphere = sphereData[j];
				Vector3 toCentre = spherePosition - spherePositions[j];
				// An unfortunately slow way of checking if the radius of the
				// other sphere should be the other spheres actual radius or
				// the user controlled spheres radius.
				float otherRadius; 
				if(j == 0)
				{
					otherRadius = userSphereSize;
				}
				else
				{
					otherRadius = (float)(indexCounter) * 0.5f;
				}

				float combinedRadius = radius + otherRadius;
				float lengthSqrd = lengthSquared(toCentre);
				float combinedRadiusSqrd = combinedRadius * combinedRadius;
				
				// A check to see if the spheres have overlapped at all.
				float overlapSqrd = lengthSqrd - combinedRadiusSqrd;
				if(overlapSqrd < 0)
				{
#if _SSE
					overlap = sqrt(lengthSqrd) - combinedRadius;
					// We want to let the vector normalize itself in SSE
					// because we can take advantage of the rsqrt instruction
					// which will be quicker than loading in a float value
					// and multiplying by the reciprocal.
					Vector3 tangent = normalize(toCentre);
#else
					// Here we can take advantage that we've already calculated
					// the actual length value so that we have the overlap and
					// can use that value again to normalize the tangent.
					float len = sqrt(lengthSqrd);
					overlap = len - combinedRadius;
					Vector3 tangent = toCentre / len;
#endif
					calcForce(forces, sphereSpringConst, sphereDampFactor, overlap, tangent, tempVelocity);
				}
			}
			
			// Calculate the overlap with the walls using the normal of the wall
			// and the walls distance from the origin. Should work best for SSE
			// as it should not require any checking of individual elements of
			// the vector.
			overlap = dot3(spherePosition, bottom) + roomSize;
			if(overlap < 0)
			{
				calcForce(forces, wallSpringConst, wallDampFactor, overlap, bottom, tempVelocity);
			}

			overlap = dot3(spherePosition, left) + roomSize;
			if(overlap < 0)
			{
				calcForce(forces, wallSpringConst, wallDampFactor, overlap, left, tempVelocity);
			}
			overlap = dot3(spherePosition, right) + roomSize;
			if(overlap < 0)
			{
				calcForce(forces, wallSpringConst, wallDampFactor, overlap, right, tempVelocity);
			}

			overlap = dot3(spherePosition, front) + roomSize;
			if(overlap < 0)
			{
				calcForce(forces, wallSpringConst, wallDampFactor, overlap, front, tempVelocity);
			}
			overlap = dot3(spherePosition, back) + roomSize;
			if(overlap < 0)
			{
				calcForce(forces, wallSpringConst, wallDampFactor, overlap, back, tempVelocity);
			}

			// Apply the accumulated forces to the acceleration.
			sphere.m_acc = forces / (radius * 2.0f);
			sphere.m_acc += GRAVITY;

			// Calculate the final velocity value from the interim velocity
			// and final acceleration.
			sphere.m_velocity = halfVelo + (0.5f * sphere.m_acc * dt);
		}

		// Determin if we need to reset out physics frame counter.
		secondCheck += dt;
		if(secondCheck > 1.0f)
		{
			physicsFrames[threadNum] = 1;
			secondCheck -= 1.0f;
		}
		else
		{
			physicsFrames[threadNum]++;
		}

		updateTimes[threadNum] = time;

		// If we're running the physics function as a thread function then we
		// need to keep it running, so this is the end of the while(programRunning) loop.
#if _USE_MT
	}
#endif
}
Esempio n. 5
0
void Bond::addContactForce(){
	calcForce();
	(*p_particle0).stackForce( force0, torque0);
	(*p_particle1).stackForce(-force0, torque1);
}