示例#1
0
/*
**
** int scatter_xover(EVOLDATA ev,
**					int iNumParents, VECTOR fProbDist, VECTOR fResult,
**					MATRIX fPop, int iPopSize)
**
** This operator :
**
** 1. Picks a set of parents.
** 2. Finds the 'central' vector by averaging the parent vectors.
** 3. Finds the worst vector among the parents.
** 4. Does a (heuristic) crossover between the worst and the central =
vector.
**
**
*/
int scatter_xover(EVOLDATA ev,
	int iNumParents, VECTOR fProbDist, VECTOR fResult,
	MATRIX fPop, int iPopSize)
{

	int i, j;
	float fRandVal;
	VECTOR fParIndexVector;		/* Indices of Parents selected */
	VECTOR fCentralVector;		/* Central vector */

	float fWorstVal; int iWorstParIndex;

	fParIndexVector = init_vector(iNumParents + 1);
	fCentralVector = init_vector(ev.iNumVars + 1);

	/* pick the req. no. of parents, and note the worst  */
	iWorstParIndex = 1;

	for (i = 1; i <= iNumParents; i++)
	{
		fRandVal = randgen(0.0, 1.0);
		j = 1;
		while ((fRandVal > fProbDist[i]) && (j < iPopSize))
			j++;
		fParIndexVector[i] = (float) j;
		if (iWorstParIndex <= j) iWorstParIndex = j;
	}

	/* now, find 'central' vector by averaging all parents */
	for (i = 1; i <= ev.iNumVars; i++)
	{
		for (j = 1; j <= iNumParents; j++)
			fCentralVector[i] = fCentralVector[i]
			+ fPop[(int) fParIndexVector[j]][i];
		fCentralVector[i] = fCentralVector[i] / iNumParents;
	}


	/* now, move from worst vector to central vector */
	/* similar to heuristic crossover */


	fRandVal = randgen(0.0, 1.0);
	for (i = 1; i <= ev.iNumVars + 1; i++)
		fResult[i] = fRandVal*(fCentralVector[i] - fPop[iWorstParIndex][i])
		+ fCentralVector[i];



	free_vector(fParIndexVector);
	free_vector(fCentralVector);

	return(iWorstParIndex);
}
示例#2
0
DWORD WINAPI fnCoches(LPVOID parametro)
{
	int posicion, carril, color, sum;
	int velocidad, tcarril;

	srand((unsigned int)time(NULL));

	do
	{
		carril = randgen(0, 1);
		sum = carril * 137;
		posicion = randgen(0, 136);
	} while (cruce(posicion, carril) || WaitForSingleObject(IPC.posiciones[posicion + sum], 0) != WAIT_OBJECT_0);

	velocidad = randgen(1, 99);
	color = randgen(0, 7);

	/*Situamos el coche en la posicion y carril calculadas arriba*/
	DLL.inicio_coche(&carril, &posicion, color);

	/*Avisamos que nos hemos creado*/
	SetEvent(IPC.evento_creacion);
	WaitForSingleObject(IPC.semaforo_pistoletazo, INFINITE); //Esperamos por el pistoletazo

	while (1)
	{
		/*Garantizamos que  estando en estas posiciones avanzo o espero que el semaforo cambie*/
		if ((posicion == 20 && carril == 0) || (posicion == 22 && carril == 1))
			WaitForSingleObject(IPC.posiciones[274], INFINITE);
		if ((posicion == 105 && carril == 0) || (posicion == 98 && carril == 1))
			WaitForSingleObject(IPC.posiciones[275], INFINITE);

		tcarril = carril;

		avanzar(&posicion, &carril, color);

		/*Incremento el contador de vueltas si estoy en estas posiciones y no cambio de carril*/
		if (((posicion == 133 && carril == 0) || (posicion == 131 && carril == 1)) && tcarril == carril)
			InterlockedIncrement((long*)(parametro));

		/*Si he cogio los mutex de arriba los libero para que el semaforo pueda cambiar de color*/
		ReleaseMutex(IPC.posiciones[274]);
		ReleaseMutex(IPC.posiciones[275]);

		DLL.velocidad(velocidad, carril, posicion);
	}

	return 1;
}
示例#3
0
/*
**
** void gauss_mutate(EVOLDATA ev, VECTOR fV, long lNumEvals)
**
** Gaussian mutation operator - single parent, single offspring
**
**
*/
void gauss_mutate(EVOLDATA ev, VECTOR fV, long lNumEvals)
{
	float fSigma, fDelta;
	float fRandVal[GENOCOP_MAXVECTOR];
	int i, j;

	fSigma = (float) ((ev.lTotEvals - lNumEvals) / ev.lTotEvals);
	for (j = 1; j <= ev.iNumVars; j++)
	{
		/* create 12 random floating point numbers between 0 and 1 */
		for (i = 1; i <= 12; ++i)
			fRandVal[i] = randgen(0.0, 1.0);

		/* delta is the total of these 12 random numbers minus 6 */
		/* note that delta might be positive or negative */
		fDelta = fRandVal[1] + fRandVal[2] +
			fRandVal[3] + fRandVal[4] +
			fRandVal[5] + fRandVal[6] +
			fRandVal[7] + fRandVal[8] +
			fRandVal[9] + fRandVal[10] +
			fRandVal[11] + fRandVal[12] - 6.0F;

		/* mutate the j-th component of the vector X */
		fV[j] = fV[j] + fSigma*fDelta;
	}

}
示例#4
0
/*
**
** int pool_xover(EVOLDATA ev,
**					int iNumParents, VECTOR fProbDist, VECTOR fResult,
**					MATRIX fPop, int iPopSize)
**
**
** Picks bits from a random parent selected from a set
** and fills up the offspring vector.  Returns  index of the
** worst parent in the set.
**
*/
int pool_xover(EVOLDATA ev,
	int iNumParents, VECTOR fProbDist, VECTOR fResult,
	MATRIX fPop, int iPopSize)
{

	int i, j, iWorstParIndex, iRandVal;
	float fRandVal;
	VECTOR fParIndexVector;


	fParIndexVector = init_vector(iNumParents + 1);


	/* pick the req. no. of parents and note index of worst */
	iWorstParIndex = 1;

	for (i = 1; i <= iNumParents; i++)
	{
		fRandVal = randgen(0.0, 1.0);
		j = 1;
		while ((fRandVal > fProbDist[i]) && (j < iPopSize))
			j++;
		fParIndexVector[i] = (float) j;
		if (iWorstParIndex <= j) iWorstParIndex = j;
	}


	/* now, pick cells from each selected parent, filling up the */
	/* offspring vector till there are no bits left */

	for (i = 1; i <= ev.iNumVars; i++)
	{
		iRandVal = (int) randgen(1.0, (float) iNumParents + 1.0);
		fResult[i] = fPop[(int) fParIndexVector[iRandVal]][i];
	}

	free_vector(fParIndexVector);

	return(iWorstParIndex);
}
示例#5
0
///////////////////
// MUD FUNCTIONS //
///////////////////
long randnum(long start, long end)
{
	static long num;

	if(start<0 || end<0)
		return randneg(start,end);

	do
	{
		num = randgen() % (end+1);
	} while( num < start || num > end );

	return num;
}
示例#6
0
/*
**
** void hr_xover(EVOLDATA ev, VECTOR fV1, VECTOR fV2, VECTOR =
fOffspring)
**
** Heuristic crossover operator - double parent, single offspring
**
**
*/
void hr_xover(EVOLDATA ev, VECTOR fV1, VECTOR fV2, VECTOR fOffspring)
{

	float  fRandVal;
	int i;

	fRandVal = randgen(0.0, 1.0);

	/* assume, as passed, BETTER PARENT IS fV1 - see top-level code */

	for (i = 1; i <= ev.iNumVars; i++)
		fOffspring[i] = fRandVal*(fV1[i] - fV2[i]) + fV1[i];

	/* check for constraints is done at top level anyway */

}
示例#7
0
void rand_seed (unsigned long a, unsigned long b, unsigned long c)
{
	static unsigned long x = 4294967295U;

	shft1=k1-p1;
	shft2=k2-p2;
	shft3=k3-p3;
	mask1 = x << (32-k1);
	mask2 = x << (32-k2);
	mask3 = x << (32-k3);
	if (a > (unsigned int)(1<<shft1)) s1 = a;
	if (b > (unsigned int)(1<<shft2)) s2 = b;
	if (c > (unsigned int)(1<<shft3)) s3 = c;

	randgen();
}
示例#8
0
task_t planes_task_with_bounds(const size_t num_planes, const moment_t timespan, const moment_t bound_timespan)
{
    mt19937 randgen(static_cast<unsigned int>(std::time(0)));
    uniform_real_distribution<float> classes_distr(0, 1);
    uniform_real_distribution<float> priorities_distr(0, 1);
    uniform_real_distribution<moment_t> bounds_distr(bound_timespan * moment_t(0.7), bound_timespan);
    uniform_real_distribution<moment_t> dates_distr(bound_timespan, timespan);
    uniform_int_distribution<size_t> names_distr(0, sizeof(names) / sizeof(string));

    task_t task(num_planes);

    for (size_t i = 0; i < num_planes; ++i)
    {
        float p = classes_distr(randgen);
        if (p < 0.2)
            task[i].class_ = aircraft_t::LIGHT;
        else if (p > 0.8)
            task[i].class_ = aircraft_t::HEAVY;
        else
            task[i].class_ = aircraft_t::MEDIUM;
    }

    for (size_t i = 0; i < num_planes; ++i)
    {
        float p = priorities_distr(randgen);
        if (p < 0.2)
            task[i].priority_ = aircraft_t::RED;
        else if (p > 0.8)
            task[i].priority_ = aircraft_t::GREEN;
        else
            task[i].priority_ = aircraft_t::YELLOW;
    }

    for (size_t i = 0; i < num_planes; ++i)
    {
        task[i].name = ::names[i];
        task[i].due = dates_distr(randgen);
        task[i].min_bound = std::max(task[i].due - bounds_distr(randgen), moment_t(0));
        //task[i].min_bound = task[i].due;
        task[i].max_bound = task[i].due + bounds_distr(randgen);
    }

    perm_t due_perm = due_dates_perm(task);
    task = apply_permutation(task, due_perm);
    return task;
}
示例#9
0
void 
simpleFluidEmitter::surfaceFluidEmitter(
	MFnFluid& 		fluid,
	const MMatrix&	fluidWorldMatrix,
	int 			plugIndex,
	MDataBlock& 	block,
	double 			dt,
	double			conversion,
	double			dropoff
)
//==============================================================================
//
//	Method:	
//
//		simpleFluidEmitter::surfaceFluidEmitter
//
//	Description:
//
//		Emits fluid from one of a predefined set of volumes (cube, sphere,
//		cylinder, cone, torus).
//
//	Parameters:
//
//		fluid:				fluid into which we are emitting
//		fluidWorldMatrix:	object->world matrix for the fluid
//		plugIndex:			identifies which fluid connected to the emitter
//							we are emitting into
//		block:				datablock for the emitter, to retrieve attribute
//							values
//		dt:					time delta for this frame
//		conversion:			mapping from UI emission rates to internal units
//		dropoff:			specifies how much emission rate drops off as
//							the surface points move away from the centers
//							of the voxels in which they lie.
//
//	Notes:
//		
//		To associate an owner object with an emitter, use the
//		addDynamic MEL command, e.g. "addDynamic simpleFluidEmitter1 pPlane1".
//
//==============================================================================
{
	//	get relevant world matrices
	//
	MMatrix fluidInverseWorldMatrix = fluidWorldMatrix.inverse();
	
	//	get emission rates for density, fuel, heat, and emission color
	//	
	double densityEmit = fluidDensityEmission( block );
	double fuelEmit = fluidFuelEmission( block );
	double heatEmit = fluidHeatEmission( block );
	bool doEmitColor = fluidEmitColor( block );
	MColor emitColor = fluidColor( block );
	
	//	rate modulation based on frame time, user value conversion factor, and
	//	standard emitter "rate" value (not actually exposed in most fluid
	//	emitters, but there anyway).
	//
	double theRate = getRate(block) * dt * conversion;

	//	get voxel dimensions and sizes (object space)
	//
	double size[3];
	unsigned int res[3];
	fluid.getDimensions( size[0], size[1], size[2] );
	fluid.getResolution( res[0], res[1], res[2] );
		
	//	voxel sizes
	double dx = size[0] / res[0];
	double dy = size[1] / res[1];
	double dz = size[2] / res[2];
	
	//	voxel centers
	double Ox = -size[0]/2;
	double Oy = -size[1]/2;
	double Oz = -size[2]/2;	

	//	get the "swept geometry" data for the emitter surface.  This structure
	//	tracks the motion of each emitter triangle over the time interval
	//	for this simulation step.  We just use positions on the emitter
	//	surface at the end of the time step to do the emission.
	//
	MDataHandle sweptHandle = block.inputValue( mSweptGeometry );
	MObject sweptData = sweptHandle.data();
	MFnDynSweptGeometryData fnSweptData( sweptData );

	//	for "non-jittered" sampling, just reset the random state for each 
	//	triangle, which gives us a fixed set of samples all the time.
	//	Sure, they're still jittered, but they're all jittered the same,
	//	which makes them kinda uniform.
	//
	bool jitter = fluidJitter(block);
	if( !jitter )
	{
		resetRandomState( plugIndex, block );
	}

	if( fnSweptData.triangleCount() > 0 )
	{
		//	average voxel face area - use this as the canonical unit that
		//	receives the emission rate specified by the users.  Scale the
		//	rate for other triangles accordingly.
		//
		double vfArea = pow(dx*dy*dz, 2.0/3.0);
		
		//	very rudimentary support for textured emission rate and
		//	textured emission color.  We simply sample each texture once
		//	at the center of each emitter surface triangle.  This will 
		//	cause aliasing artifacts when these triangles are large.
		//
		MFnDependencyNode fnNode( thisMObject() );
		MObject rateTextureAttr = fnNode.attribute( "textureRate" );
		MObject colorTextureAttr = fnNode.attribute( "particleColor" );

		bool texturedRate = hasValidEmission2dTexture( rateTextureAttr );
		bool texturedColor = hasValidEmission2dTexture( colorTextureAttr );
		
		//	construct texture coordinates for each triangle center
		//	
		MDoubleArray uCoords, vCoords;
		if( texturedRate || texturedColor )
		{
			uCoords.setLength( fnSweptData.triangleCount() );
			vCoords.setLength( fnSweptData.triangleCount() );
			
			int t;
			for( t = 0; t < fnSweptData.triangleCount(); t++ )
			{
				MDynSweptTriangle tri = fnSweptData.sweptTriangle( t );
				MVector uv0 = tri.uvPoint(0);
				MVector uv1 = tri.uvPoint(1);
				MVector uv2 = tri.uvPoint(2);
				
				MVector uvMid = (uv0+uv1+uv2)/3.0;
				uCoords[t] = uvMid[0];
				vCoords[t] = uvMid[1];
			}
		}

		//	evaluate textured rate and color values at the triangle centers
		//
		MDoubleArray texturedRateValues;
		if( texturedRate )
		{
			texturedRateValues.setLength( uCoords.length() );
			evalEmission2dTexture( rateTextureAttr, uCoords, vCoords, NULL, &texturedRateValues );
		}
		
		MVectorArray texturedColorValues;
		if( texturedColor )
		{
			texturedColorValues.setLength( uCoords.length() );
			evalEmission2dTexture( colorTextureAttr, uCoords, vCoords, &texturedColorValues, NULL );
		}
		
		for( int t = 0; t < fnSweptData.triangleCount(); t++ )
		{
			//	calculate emission rate and color values for this triangle
			//
			double curTexturedRate = texturedRate ? texturedRateValues[t] : 1.0;
			MColor curTexturedColor;
			if( texturedColor )
			{
				MVector& curVec = texturedColorValues[t];
				curTexturedColor.r = (float)curVec[0];
				curTexturedColor.g = (float)curVec[1];
				curTexturedColor.b = (float)curVec[2];
				curTexturedColor.a = 1.0;
			}
			else
			{
				curTexturedColor = emitColor;
			}

			MDynSweptTriangle tri = fnSweptData.sweptTriangle( t );
			MVector v0 = tri.vertex(0);
			MVector v1 = tri.vertex(1);
			MVector v2 = tri.vertex(2);

			//	compute number of samples for this triangle based on area,
			//	with large triangles receiving approximately 1 sample for 
			//	each voxel that they intersect
			//
			double triArea = tri.area();
			int numSamples = (int)(triArea / vfArea);
			if( numSamples < 1 ) numSamples = 1;
			
			//	compute emission rate for the points on the triangle.
			//	Scale the canonical rate by the area ratio of this triangle
			//	to the average voxel size, then split it amongst all the samples.
			//
			double triRate = (theRate*(triArea/vfArea))/numSamples;
			
			triRate *= curTexturedRate;
			
			for( int j = 0; j < numSamples; j++ )
			{
				//	generate a random point on the triangle,
				//	map it into fluid local space
				//
				double r1 = randgen();
				double r2 = randgen();
				
				if( r1 + r2 > 1 )
				{
					r1 = 1-r1;
					r2 = 1-r2;
				}
				double r3 = 1 - (r1+r2);
				MPoint randPoint = r1*v0 + r2*v1 + r3*v2;
				randPoint *= fluidInverseWorldMatrix;
				
				//	figure out where the current point lies
				//
				::int3 coord;
				fluid.toGridIndex( randPoint, coord );
				
				if( (coord[0]<0) || (coord[1]<0) || (coord[2]<0) ||
					(coord[0]>=(int)res[0]) || (coord[1]>=(int)res[1]) || (coord[2]>=(int)res[2]) )
				{
					continue;
				}
				
				//	do some falloff based on how far from the voxel center 
				//	the current point lies
				//
				MPoint gridPoint;
				gridPoint.x = Ox + (coord[0]+0.5)*dx;
				gridPoint.y = Oy + (coord[1]+0.5)*dy;
				gridPoint.z = Oz + (coord[2]+0.5)*dz;
				
				MVector diff = gridPoint - randPoint;
				double distSquared = diff * diff;
				double distDrop = dropoff * distSquared;
				
				double newVal = triRate * exp( -distDrop );
		
				//	emit into the voxel
				//
				if( newVal != 0 )
				{
					fluid.emitIntoArrays( (float) newVal, coord[0], coord[1], coord[2], (float)densityEmit, (float)heatEmit, (float)fuelEmit, doEmitColor, curTexturedColor );		
				}
			}
		}
	}
}
示例#10
0
void 
simpleFluidEmitter::volumeFluidEmitter(
	MFnFluid& 		fluid,
	const MMatrix&	fluidWorldMatrix,
	int 			plugIndex,
	MDataBlock& 	block,
	double 			dt,
	double			conversion,
	double			dropoff
)
//==============================================================================
//
//	Method:	
//
//		simpleFluidEmitter::volumeFluidEmitter
//
//	Description:
//
//		Emits fluid from points distributed over the surface of the 
//		emitter's owner object.
//
//	Parameters:
//
//		fluid:				fluid into which we are emitting
//		fluidWorldMatrix:	object->world matrix for the fluid
//		plugIndex:			identifies which fluid connected to the emitter
//							we are emitting into
//		block:				datablock for the emitter, to retrieve attribute
//							values
//		dt:					time delta for this frame
//		conversion:			mapping from UI emission rates to internal units
//		dropoff:			specifies how much emission rate drops off as
//							we move away from the local y-axis of the 
//							volume emitter shape.
//
//==============================================================================
{
	//	get emitter position and relevant matrices 
	//	
	MPoint emitterPos = getWorldPosition();
	MMatrix emitterWorldMatrix = getWorldMatrix();
	MMatrix fluidInverseWorldMatrix = fluidWorldMatrix.inverse();
	
	//	get emission rates for density, fuel, heat, and emission color
	//	
	double densityEmit = fluidDensityEmission( block );
	double fuelEmit = fluidFuelEmission( block );
	double heatEmit = fluidHeatEmission( block );
	bool doEmitColor = fluidEmitColor( block );
	MColor emitColor = fluidColor( block );
	
	//	rate modulation based on frame time, user value conversion factor, and
	//	standard emitter "rate" value (not actually exposed in most fluid
	//	emitters, but there anyway).
	//
	double theRate = getRate(block) * dt * conversion;
	
	//	get voxel dimensions and sizes (object space)
	//
	double size[3];
	unsigned int res[3];
	fluid.getDimensions( size[0], size[1], size[2] );
	fluid.getResolution( res[0], res[1], res[2] );

	//	voxel sizes
	double dx = size[0] / res[0];
	double dy = size[1] / res[1];
	double dz = size[2] / res[2];
	
	// 	voxel centers
	double Ox = -size[0]/2;
	double Oy = -size[1]/2;
	double Oz = -size[2]/2;	

	//	find the voxels that intersect the bounding box of the volume
	//	primitive associated with the emitter
	//
	MBoundingBox bbox;
	if( !volumePrimitiveBoundingBox( bbox ) )
	{
		//	shouldn't happen
		//
		return;
	}
	
	//	transform volume primitive into fluid space
	//
	bbox.transformUsing( emitterWorldMatrix );
	bbox.transformUsing( fluidInverseWorldMatrix );
	MPoint lowCorner = bbox.min();
	MPoint highCorner = bbox.max();

	//	get fluid voxel coord range of bounding box
	//
	::int3 lowCoords;
	::int3 highCoords;
	fluid.toGridIndex( lowCorner, lowCoords );
	fluid.toGridIndex( highCorner, highCoords );
	
	int i;
	for ( i = 0; i < 3; i++ )
	{
		if ( lowCoords[i] < 0 ) {
			lowCoords[i] = 0;
		} else if ( lowCoords[i] > ((int)res[i])-1 ) {
			lowCoords[i] = ((int)res[i])-1;
		}

		if ( highCoords[i] < 0 ) {
			highCoords[i] = 0;
		} else if ( highCoords[i] > ((int)res[i])-1 ) {
			highCoords[i] = ((int)res[i])-1;
		}
		
	}

	//	figure out the emitter size relative to the voxel size, and compute
	//	a per-voxel sampling rate that uses 1 sample/voxel for emitters that
	//	are >= 2 voxels big in all dimensions.  For smaller emitters, use up
	//	to 8 samples per voxel.
	//
	double emitterVoxelSize[3];
	emitterVoxelSize[0] = (highCorner[0]-lowCorner[0])/dx;
	emitterVoxelSize[1] = (highCorner[1]-lowCorner[1])/dy;
	emitterVoxelSize[2] = (highCorner[2]-lowCorner[2])/dz;
		
	double minVoxelSize = MIN(emitterVoxelSize[0],MIN(emitterVoxelSize[1],emitterVoxelSize[2]));
	if( minVoxelSize < 1.0 )
	{
		minVoxelSize = 1.0;
	}
	int maxSamples = 8;
	int numSamples = (int)(8.0/(minVoxelSize*minVoxelSize*minVoxelSize) + 0.5);
	if( numSamples < 1 ) numSamples = 1;
	if( numSamples > maxSamples ) numSamples = maxSamples;
	
	//	non-jittered, just use one sample in the voxel center.  Should replace
	//	with uniform sampling pattern.
	//
	bool jitter = fluidJitter(block);
	if( !jitter )
	{
		numSamples = 1;
	}
	
	//	for each voxel that could potentially intersect the volume emitter
	//	primitive, take some samples in the voxel.  For those inside the
	//	volume, compute their dropoff relative to the primitive's local y-axis,
	//	and emit an appropriate amount into the voxel.
	//
	for( i = lowCoords[0]; i <= highCoords[0]; i++ )
	{
		double x = Ox + (i+0.5)*dx;
			
		for( int j = lowCoords[1]; j < highCoords[1]; j++ )
		{
			double y = Oy + (j+0.5)*dy;

			for( int k = lowCoords[2]; k < highCoords[2]; k++ )
			{
				double z = Oz + (k+0.5)*dz;
				
				for ( int si = 0; si < numSamples; si++) {
					
					//	compute voxel sample point (object space)
					//
					double rx, ry, rz;
					if(jitter) {
						rx = x + dx*(randgen() - 0.5);
						ry = y + dy*(randgen() - 0.5);
						rz = z + dz*(randgen() - 0.5);
					} else {
						rx = x;
						ry = y;
						rz = z;
					}
					
					//	to world space
					MPoint pt( rx, ry, rz );
					pt *= fluidWorldMatrix;

					//	test to see if point is inside volume primitive
					//
					if( volumePrimitivePointInside( pt, emitterWorldMatrix ) )
					{
						//	compute dropoff
						//
						double dist = pt.distanceTo( emitterPos );
						double distDrop = dropoff * (dist*dist);
						double newVal = (theRate * exp( -distDrop )) / (double)numSamples;
						
						//	emit into arrays
						//
						if( newVal != 0.0 )
						{
							fluid.emitIntoArrays( (float) newVal, i, j, k, (float)densityEmit, (float)heatEmit, (float)fuelEmit, doEmitColor, emitColor );
						}
					}
				}
			}
		}
	}
}
示例#11
0
void 
simpleFluidEmitter::omniFluidEmitter(
	MFnFluid& 		fluid,
	const MMatrix&	fluidWorldMatrix,
	int 			plugIndex,
	MDataBlock& 	block,
	double 			dt,
	double			conversion,
	double			dropoff
)
//==============================================================================
//
//	Method:	
//
//		simpleFluidEmitter::omniFluidEmitter
//
//	Description:
//
//		Emits fluid from a point, or from a set of object control points.
//
//	Parameters:
//
//		fluid:				fluid into which we are emitting
//		fluidWorldMatrix:	object->world matrix for the fluid
//		plugIndex:			identifies which fluid connected to the emitter
//							we are emitting into
//		block:				datablock for the emitter, to retrieve attribute
//							values
//		dt:					time delta for this frame
//		conversion:			mapping from UI emission rates to internal units
//		dropoff:			specifies how much emission rate drops off as
//							we move away from each emission point.
//
//	Notes:
//
//		If no owner object is present for the emitter, we simply emit from
//		the emitter position.  If an owner object is present, then we emit
//		from each control point of that object in an identical fashion.
//		
//		To associate an owner object with an emitter, use the
//		addDynamic MEL command, e.g. "addDynamic simpleFluidEmitter1 pPlane1".
//
//==============================================================================
{
	//	find the positions that we need to emit from
	//
	MVectorArray emitterPositions;
	
	//	first, try to get them from an owner object, which will have its
	//	"ownerPositionData" attribute feeding into the emitter.  These
	//	values are in worldspace
	//
	bool gotOwnerPositions = false;
	MObject ownerShape = getOwnerShape();
	if( ownerShape != MObject::kNullObj )
	{
		MStatus status;
		MDataHandle hOwnerPos = block.inputValue( mOwnerPosData, &status );
		if( status == MS::kSuccess )
		{
			MObject dOwnerPos = hOwnerPos.data();
			MFnVectorArrayData fnOwnerPos( dOwnerPos );
			MVectorArray posArray = fnOwnerPos.array( &status );
			if( status == MS::kSuccess )
			{
				// assign vectors from block to ownerPosArray.
				//
				for( unsigned int i = 0; i < posArray.length(); i ++ )
				{
					emitterPositions.append( posArray[i] );
				}
				
				gotOwnerPositions = true;
			}
		}
	}
	
	//	there was no owner object, so we just use the emitter position for
	//	emission.
	//
	if( !gotOwnerPositions )
	{
		MPoint emitterPos = getWorldPosition();
		emitterPositions.append( emitterPos );
	}

	//	get emission rates for density, fuel, heat, and emission color
	//	
	double densityEmit = fluidDensityEmission( block );
	double fuelEmit = fluidFuelEmission( block );
	double heatEmit = fluidHeatEmission( block );
	bool doEmitColor = fluidEmitColor( block );
	MColor emitColor = fluidColor( block );

	//	rate modulation based on frame time, user value conversion factor, and
	//	standard emitter "rate" value (not actually exposed in most fluid
	//	emitters, but there anyway).
	//
	double theRate = getRate(block) * dt * conversion;

	//	get voxel dimensions and sizes (object space)
	//
	double size[3];
	unsigned int res[3];
	fluid.getDimensions( size[0], size[1], size[2] );
	fluid.getResolution( res[0], res[1], res[2] );
	
	//	voxel sizes
	double dx = size[0] / res[0];
	double dy = size[1] / res[1];
	double dz = size[2] / res[2];
	
	//	voxel centers
	double Ox = -size[0]/2;
	double Oy = -size[1]/2;
	double Oz = -size[2]/2;	

	//	emission will only happen for voxels whose centers lie within
	//	"minDist" and "maxDist" of an emitter position
	//
	double minDist = getMinDistance( block );
	double maxDist = getMaxDistance( block );

	//	bump up the min/max distance values so that they
	//	are both > 0, and there is at least about a half
	//	voxel between the min and max values, to prevent aliasing
	//	artifacts caused by emitters missing most voxel centers
	//
	MTransformationMatrix fluidXform( fluidWorldMatrix );
	double fluidScale[3];
	fluidXform.getScale( fluidScale, MSpace::kWorld );
	
	//	compute smallest voxel diagonal length
	double wsX =  fabs(fluidScale[0]*dx);
	double wsY = fabs(fluidScale[1]*dy);
	double wsZ = fabs(fluidScale[2]*dz);
	double wsMin = MIN( MIN( wsX, wsY), wsZ );
	double wsMax = MAX( MAX( wsX, wsY), wsZ );
	double wsDiag  = wsMin * sqrt(3.0);

	//	make sure emission range is bigger than 0.5 voxels
	if ( maxDist <= minDist || maxDist <= (wsDiag/2.0) ) {
		if ( minDist < 0 ) minDist = 0;

		maxDist = minDist + wsDiag/2.0;
		dropoff = 0;
	}

	//	Now, it's time to actually emit into the fluid:
	//	
	//	foreach emitter point
	//		foreach voxel
	//			- select some points in the voxel
	//			- compute a dropoff function from the emitter point
	//			- emit an appropriate amount of fluid into the voxel
	//
	//	Since we've already expanded the min/max distances to cover
	//	the smallest voxel dimension, we should only need 1 sample per
	//	voxel, unless the voxels are highly non-square.  We increase the
	//	number of samples in these cases.
	//
	//	If the "jitter" flag is enabled, we jitter each sample position,
	//	using the rangen() function, which keeps track of independent 
	//	random states for each fluid, to make sure that results are
	//	repeatable for multiple simulation runs.
	//	

	// basic sample count
	int numSamples = 1;

	// increase samples if necessary for non-square voxels
	if(wsMin >.00001) 
	{
		numSamples = (int)(wsMax/wsMin + .5);
		if(numSamples > 8) 
			numSamples = 8;
		if(numSamples < 1)
			numSamples = 1;
	}
	
	bool jitter =  fluidJitter(block);
	if( !jitter )
	{
		//	I don't have a good uniform sample generator for an 
		//	arbitrary number of samples.  It would be a good idea to use
		//	one here.  For now, just use 1 sample for the non-jittered case.
		//
		numSamples = 1;
	}

	for( unsigned int p = 0; p < emitterPositions.length(); p++ )
	{
		MPoint emitterWorldPos = emitterPositions[p];

		//	loop through all voxels, looking for ones that lie at least
		//	partially within the dropoff field around this emitter point
		//
		for( unsigned int i = 0; i < res[0]; i++ )
		{
			double x = Ox + i*dx;
			
			for( unsigned int j = 0; j < res[1]; j++ )
			{
				double y = Oy + j*dy;
				
				for( unsigned int k = 0; k < res[2]; k++ )
				{
					double z = Oz + k*dz;
	
					int si;
					for( si = 0; si < numSamples; si++ )
					{
						//	compute sample point (fluid object space)
						//
						double rx, ry, rz;
						if( jitter )
						{
							rx = x + randgen()*dx;
							ry = y + randgen()*dy;
							rz = z + randgen()*dz;
						}
						else
						{
							rx = x + 0.5*dx;
							ry = y + 0.5*dy;
							rz = z + 0.5*dz;
						}

						//	compute distance from sample to emitter point
						//	
						MPoint point( rx, ry, rz );
						point *= fluidWorldMatrix;
						MVector diff = point - emitterWorldPos;
						double distSquared = diff * diff;
						double dist = diff.length();
					
						//	discard if outside min/max range
						//
						if( (dist < minDist) || (dist > maxDist) )
						{
							continue;
						}
						
						//	drop off the emission rate according to the falloff
						//	parameter, and divide to accound for multiple samples
						//	in the voxel
						//
						double distDrop = dropoff * distSquared;
						double newVal = theRate * exp( -distDrop ) / (double)numSamples;

						//	emit density/heat/fuel/color into the current voxel
						//
						if( newVal != 0 )
						{
							fluid.emitIntoArrays( (float) newVal, i, j, k, (float)densityEmit, (float)heatEmit, (float)fuelEmit, doEmitColor, emitColor );
						}

						float *fArray = fluid.falloff();
						if( fArray != NULL )
						{
							MPoint midPoint( x+0.5*dx, y+0.5*dy, z+0.5*dz );
							midPoint.x *= 0.2;
							midPoint.y *= 0.2;
							midPoint.z *= 0.2;

							float fdist = (float) sqrt( midPoint.x*midPoint.x + midPoint.y*midPoint.y + midPoint.z*midPoint.z );
							fdist /= sqrtf(3.0f);
							fArray[fluid.index(i,j,k)] = 1.0f-fdist;
						}
					}
				}
			}
		}
	}
}
示例#12
0
// private method to work with random generation and Normal distributions.
// in it we are using the random support offered by the thrust library
__device__ __host__ float ExampleTanNoise::NORM(int pos, int seed) const {
  thrust::minstd_rand randgen(seed);
  thrust::random::normal_distribution<float> dist;
  randgen.discard(pos);
  return dist(randgen);
}
示例#13
0
/*
**
** void	setup_spop(EVOLDATA ev, MATRIX fSearchPop, VECTOR fRefProbDist,
**						MATRIX fRefPop, MATRIX fLC, MATRIX fDC)
**						
** Sets up the search population by performing the initial evaluations.
**
** Assumes that ref. population is already setup and SORTED
**
*/
void	setup_spop(EVOLDATA ev, MATRIX fSearchPop, VECTOR fRefProbDist,
						MATRIX fRefPop, MATRIX fLC, MATRIX fDC)
{
	int i, j, k, iSelIndex;
	float fRandVal;
	float fTempVec[MAXVECTOR];
	int	iFlag;

	for (i=1; i<=ev.iSearchPopSize; i++)
	{
		eval_func(fSearchPop[i], ev.iNumTestCase, ev);  /* simple evaluation */

		
		/* now, pick a reference vector at RANDOM (0) or ORDERED (1) */
		if (ev.iSelRefPoint == RANDOM)
			iSelIndex = (int)randgen(1.0, (float)ev.iRefPopSize);
		else
		{	
		fRandVal = randgen(0.0, 1.0);
		k=1;
		while (fRandVal >= fRefProbDist[k])
			k++;
		if (k >= ev.iRefPopSize) k = 1;
		iSelIndex = k;
		}
						
		/* move from search to reference */
		k = 0; iFlag = FALSE; fRandVal = 0.0;

		if (ev.iRepairMethod == RANDOM)
		do
		{
			fRandVal = randgen(0.0, 1.0);
			
			for (j=1; j<=ev.iNumVars; j++)
				fTempVec[j] = fRandVal*fSearchPop[i][j] +
								(1-fRandVal)*fRefPop[iSelIndex][j];
								
			iFlag = check_all(ev, fTempVec, fLC, fDC);
			k++;
		} while ((iFlag == FALSE) && (k < 100));
		else if (ev.iRepairMethod == DETERMINISTIC)
		do
		{
			fRandVal = 1.0/power(2.0, k);
			for (j=1; j<=ev.iNumVars; j++)
				fTempVec[j] = fRandVal*fSearchPop[i][j] +
								(1-fRandVal)*fRefPop[iSelIndex][j];		
			iFlag = check_all(ev, fTempVec, fLC, fDC);
			k++;
		} while ((iFlag == FALSE) && (k < 20));
		
		/* if no feasible Z, Z = Y */
		if (iFlag == FALSE)
			for (j=1; j<=ev.iNumVars; j++)
				fTempVec[j] = fRefPop[iSelIndex][j];
		
		/* now, evaluate Z */
		eval_func(fTempVec, ev.iNumTestCase, ev);
		
		/* if Z better than Y, replace Y by Z */
		switch(ev.iObjFnType)
		{
			case MAX:
				if (fTempVec[0] >  fRefPop[iSelIndex][0])
					for (j=0; j<=ev.iNumVars; j++)
						fRefPop[iSelIndex][j] = fTempVec[j];
				break;
			case MIN:
				if (fTempVec[0] <  fRefPop[iSelIndex][0])
					for (j=0; j<=ev.iNumVars; j++)
						fRefPop[iSelIndex][j] = fTempVec[j];
				break;
			default:
				break;
		}
		
		/* eval(X) = eval(Z) */
		fSearchPop[i][0] = fTempVec[0];
		/* if probability allows, replace X by Z as well */
		fRandVal = randgen(0.0, 1.0);
		if (fRandVal < ev.fReplRatio)
			for (j=0; j<=ev.iNumVars; j++)
				fSearchPop[i][j] = fTempVec[j];
				
		
	}

}
示例#14
0
/*
**
** void b_mutate(EVOLDATA ev, VECTOR fV, int iIndex, MATRIX fDC, MATRIX =
fLC)
**
** Boundary mutation operator - single parent, single offspring
**
**
*/
void b_mutate(EVOLDATA ev, VECTOR fV, int iIndex, MATRIX fDC, MATRIX fLC)
{
	int i, j, iFlag;
	float fLlim, fUlim, fSum, fNewLimit, fRandVal;

	iFlag = GENOCOP_FALSE;
	/* see if the chosen variable has any Domain Constraints */
	for (i = 1; i <= ev.iNumDC; i++)
	{
		if ((int) fDC[i][2] == iIndex)
		{
			fUlim = fDC[i][3];
			fLlim = fDC[i][1];
			iFlag = GENOCOP_TRUE;
		}
	}
	if (iFlag == GENOCOP_FALSE)
	{

		fUlim = GENOCOP_MAXNUM;
		fLlim = GENOCOP_MINNUM;
	}

	/* now, get new limit from linear constraints */
	/* for this, first substitute all other variables */
	/* keeping in mind that the function is stated as f[x] >= 0 */

	for (i = 1; i <= ev.iNumLC; i++)
	{
		/*
		** CHECK LIMITS ONLY IF COEFF. OF VARIABLE IS NON-ZERO
		**
		*/
		if (fLC[i][iIndex] != 0.0)
		{
			fSum = 0.0;
			for (j = 1; j <= ev.iNumVars; j++)
			if (j != iIndex)
				fSum = fSum + fV[j] * fLC[i][j];
			fSum = fSum + fLC[i][ev.iNumVars + 1];	/* constant term */
			/* now, function is fSum+fV[iIndex]*fLC[i][iIndex] >= 0 */
			/* this is the new lower limit, after comparison */
			fNewLimit = (-1 * fSum) / fLC[i][iIndex];

			/* now, if the coeff. was NEGATIVE, the inequality is CHANGED */
			/* while carrying it over, and it becomes a possible new */
			/* LOWER limit */
			if (fLC[i][iIndex] > 0.0)	/* CHANGE SIGN IF NEGATIVE */
			{
				if (fNewLimit > fLlim)
					fLlim = fNewLimit;
			}
			else
			{
				if (fNewLimit < fUlim)
					fUlim = fNewLimit;
			}
		}

	}

	/* pick either the max or min. limit */
	fRandVal = randgen(0.0, 1.0);
	if (fRandVal < 0.5)
		fV[iIndex] = fLlim;
	else
		fV[iIndex] = fUlim;
}
示例#15
0
TestMRPPWindow::TestMRPPWindow(HWND parent, std::string title) : MRPWindow(parent, title)
{
	for (int i = 0; i < 8; ++i)
	{
		auto but = std::make_shared<WinButton>(this, std::to_string(i));
		but->GenericNotifyCallback = [i](GenericNotifications)
		{
			readbg() << "you pressed " << i << "\n";
		};
		add_control(but);
	}
	// Button 0 toggless enabled state of button 1
	m_controls[0]->GenericNotifyCallback = [this](GenericNotifications)
	{
		m_controls[1]->setEnabled(!m_controls[1]->isEnabled());
	};
	m_envcontrol1 = std::make_shared<EnvelopeControl>(this);

	// Button 3 toggless enabled state of envelope control
	m_controls[3]->GenericNotifyCallback = [this](GenericNotifications)
	{
		m_envcontrol1->setEnabled(!m_envcontrol1->isEnabled());
	};

	// Button 7 toggless visible state of button 0
	m_controls[7]->GenericNotifyCallback = [this](GenericNotifications)
	{
		m_controls[0]->setVisible(!m_controls[0]->isVisible());
	};
	auto env = std::make_shared<breakpoint_envelope>("foo", LICE_RGBA(255, 255, 255, 255));
	env->add_point({ 0.0, 0.5 , envbreakpoint::Power, 0.5 }, true);
	env->add_point({ 0.5, 0.0 , envbreakpoint::Power, 0.5 }, true);
	env->add_point({ 1.0, 0.5 }, true);
	m_envcontrol1->add_envelope(env);

	m_envcontrol1->GenericNotifyCallback = [this, env](GenericNotifications reason)
	{
		//if (reason == GenericNotifications::AfterManipulation)
		//	generate_items_sequence(env, m_edit1->getText().c_str());
	};

	add_control(m_envcontrol1);

	// Button 5 does some Xenakios silliness
	m_controls[5]->GenericNotifyCallback = [this, env](GenericNotifications)
	{
		generate_items_sequence(env, m_edit1->getText().c_str());
	};

	m_label1 = std::make_shared<WinLabel>(this, "This is a label");
	add_control(m_label1);

	m_edit1 = std::make_shared<WinLineEdit>(this, "C:/MusicAudio/pihla_ei/ei_mono_005.wav");
	add_control(m_edit1);
	m_edit1->TextCallback = [this](std::string txt)
	{
		m_label1->setText(txt);
	};
	// Button 6 launches bogus work in another thread to demo progress bar
	m_controls[6]->GenericNotifyCallback = [this](GenericNotifications)
	{
		m_progressbar1->setVisible(true);
		// we don't deal with multiple background tasks now, so disable the button to start the task
		m_controls[6]->setEnabled(false);
		static int rseed = 0;
		auto task = [this](int randseed)
		{
			std::mt19937 randgen(randseed);
			std::uniform_real_distribution<double> randdist(0.0, 1.0);
			double accum = 0.0;
			const int iterations = 50000000;
			double t0 = time_precise();
			for (int i = 0; i < iterations; ++i)
			{
				accum += randdist(randgen);
				//accum += randdist(randgen);
				// Production code should not do this at this granularity, because setProgressValue deals with
				// an atomic value. but this is just a demo...
				m_progressbar1->setProgressValue(1.0 / iterations*i);
			}
			double t1 = time_precise();
			auto finishtask = [=]()
			{
				m_edit1->setText(std::to_string(accum) + " elapsed time " + std::to_string(t1-t0));
				m_progressbar1->setProgressValue(0.0);
				m_progressbar1->setVisible(false);
				m_controls[6]->setEnabled(true);
			};
			execute_in_main_thread(finishtask);
		};
		m_future1 = std::async(std::launch::async, task, rseed);
		++rseed;
	};
	// Button 1 shows popup menu
	m_controls[1]->GenericNotifyCallback = [this, env](GenericNotifications)
	{
		PopupMenu popmenu(getWindowHandle());
		popmenu.add_menu_item("Menu entry 1", [](PopupMenu::CheckState) {});
		popmenu.add_menu_item("Menu entry 2", m_menuitem2state, [this](PopupMenu::CheckState cs)
		{
			m_menuitem2state = cs;
		});
		popmenu.add_menu_item("Menu entry 3", m_menuitem3state, [this](PopupMenu::CheckState cs) 
		{
			m_menuitem3state = cs;
		});
		PopupMenu submenu(getWindowHandle());
		submenu.add_menu_item("Submenu entry 1", [](PopupMenu::CheckState) { readbg() << "submenu entry 1\n"; });
		submenu.add_menu_item("Submenu entry 2", [](PopupMenu::CheckState) { readbg() << "submenu entry 2\n"; });
		PopupMenu subsubmenu(getWindowHandle());
		for (int i = 0; i < 8; ++i)
		{
			subsubmenu.add_menu_item(std::string("Subsubmenu entry ") + std::to_string(i + 1), [i](PopupMenu::CheckState) 
			{
				readbg() << "subsubmenu entry " << i + 1 << "\n";
			});
		}
		submenu.add_submenu("Going still deeper", subsubmenu);
		popmenu.add_submenu("More stuff", submenu);
		popmenu.execute(m_controls[1]->getXPosition(), m_controls[1]->getYPosition());
	};
	// Button 4 removes envelope points with value over 0.5
	m_controls[4]->GenericNotifyCallback = [this, env](GenericNotifications)
	{
		env->remove_points_conditionally([](const envbreakpoint& pt)
		{ return pt.get_y() > 0.5; });
		m_envcontrol1->repaint();
	};
	m_combo1 = std::make_shared<WinComboBox>(this);
	m_combo1->addItem("Apple", -9001);
	m_combo1->addItem("Pear", 666);
	m_combo1->addItem("Kiwi", 42);
	m_combo1->addItem("Banana", 100);
	m_combo1->SelectedChangedCallback = [this](int index)
	{
		int user_id = m_combo1->userIDfromIndex(index);
		readbg() << "combo index " << index << " userid " << user_id << "\n";
	};
	add_control(m_combo1);
	m_combo1->setSelectedUserID(42);

	m_combo2 = std::make_shared<WinComboBox>(this);
	m_combo2->addItem("Item 1", 100);
	m_combo2->addItem("Item 2", 101);
	m_combo2->addItem("Item 3", 102);
	m_combo2->addItem("Item 4", 103);
	m_combo2->SelectedChangedCallback = [this](int index)
	{
		int user_id = m_combo2->userIDfromIndex(index);
		readbg() << "combo index " << index << " userid " << user_id << "\n";
	};
	add_control(m_combo2);
	m_combo2->setSelectedIndex(0);

	m_slider1 = std::make_shared<ReaSlider>(this, 0.5);
	//m_slider1->setValueConverter(std::make_shared<FFTSizesValueConverter>());
	m_slider1->SliderValueCallback = [this](GenericNotifications, double x)
	{
		m_label1->setText(std::to_string(x));
		m_progressbar1->setProgressValue(x);
	};
	add_control(m_slider1);
	m_zoomscroll1 = std::make_shared<ZoomScrollBar>(this);
	add_control(m_zoomscroll1);
	m_zoomscroll1->RangeChangedCallback = [this](double t0, double t1)
	{
		m_envcontrol1->setViewTimeRange(t0, t1);
	};

	m_progressbar1 = std::make_shared<ProgressControl>(this);
	m_progressbar1->setVisible(false);
}
AsymetricCharacterRbDemo::AsymetricCharacterRbDemo(hkDemoEnvironment* env)
:	hkDefaultPhysicsDemo(env)
{
		
	// Create the world
	{
		hkpWorldCinfo info;
		info.setBroadPhaseWorldSize( 350.0f );  
		info.m_gravity.set(0, -9.8f, 0);
		info.m_collisionTolerance = 0.01f;		
		info.m_contactPointGeneration = hkpWorldCinfo::CONTACT_POINT_ACCEPT_ALWAYS;
		m_world = new hkpWorld( info );
		m_world->lock();

		hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher());

		setupGraphics();
	}
	
	//	Create a terrain (more bumpy as in the classical character proxy demo)
	TerrainHeightFieldShape* heightFieldShape;
	{
		hkpSampledHeightFieldBaseCinfo ci;
		ci.m_xRes = 64;
		ci.m_zRes = 64;
		ci.m_scale.set(1.6f, 0.2f, 1.6f);

		// Fill in a data array
		m_data = hkAllocate<hkReal>((ci.m_xRes * ci.m_zRes), HK_MEMORY_CLASS_DEMO);
		
		for (int x = 0; x < ci.m_xRes; x++)
		{
			for (int z = 0; z < ci.m_zRes; z++)
			{
				hkReal dx,dz,height = 0;
				int octave = 1;
				
				// Add together a few sine and cose waves
				for (int i=0; i< 3; i++)
				{
					dx = hkReal(x * octave) / ci.m_xRes;
					dz = hkReal(z * octave) / ci.m_zRes;
					height +=  4 * i * hkMath::cos(dx * HK_REAL_PI) * hkMath::sin(dz * HK_REAL_PI);
					height -= 2.5f;
					octave *= 2;				
				}

				m_data[x*ci.m_zRes + z] = height;
			}
		}

		heightFieldShape = new TerrainHeightFieldShape( ci , m_data );
		
		//	Create terrain as a fixed rigid body
		{
			hkpRigidBodyCinfo rci;
			rci.m_motionType = hkpMotion::MOTION_FIXED;
			rci.m_position.setMul4( -0.5f, heightFieldShape->m_extents ); // center the heighfield
			rci.m_shape = heightFieldShape;
			rci.m_friction = 0.5f;
			
			hkpRigidBody* terrain = new hkpRigidBody( rci );

			m_world->addEntity(terrain);

			terrain->removeReference();
		}

		heightFieldShape->removeReference();
	}
	
	// Create some random static pilars (green) and smaller dynamic boxes (blue)
	{
		hkPseudoRandomGenerator randgen(12345);

		for (int i=0; i < 80; i++)
		{
			
			if (i%2)
			{
				// Dynamic boxes of random size
				hkVector4 size;
				randgen.getRandomVector11(size);
				size.setAbs4( size );
				size.mul4(0.5f);
				hkVector4 minSize; minSize.setAll3(0.25f);
				size.add4(minSize);
				
				// Random position
				hkVector4 position;
				randgen.getRandomVector11( position );
				position(0) *= 25; position(2) *= 25; position(1) = 4;

				{ 
					// To illustrate using the shape, create a rigid body by first defining a template.
					hkpRigidBodyCinfo rci;
					rci.m_shape = new hkpBoxShape( size );
					rci.m_position = position;
					rci.m_friction = 0.5f;
					rci.m_restitution = 0.0f;
					// Density of concrete
					const hkReal density = 2000.0f;
					rci.m_mass = size(0)*size(1)*size(2)*density;
					
					hkVector4 halfExtents(size(0) * 0.5f, size(1) * 0.5f, size(2) * 0.5f);
					hkpMassProperties massProperties;
					hkpInertiaTensorComputer::computeBoxVolumeMassProperties(halfExtents, rci.m_mass, massProperties);
					rci.m_inertiaTensor = massProperties.m_inertiaTensor;
					rci.m_motionType = hkpMotion::MOTION_BOX_INERTIA;
										
					// Create a rigid body (using the template above).
					hkpRigidBody* box = new hkpRigidBody(rci);

					// Remove reference since the body now "owns" the Shape.
					rci.m_shape->removeReference();

					box->addProperty(HK_PROPERTY_DEBUG_DISPLAY_COLOR, int(hkColor::DARKBLUE)); 

					// Finally add body so we can see it, and remove reference since the world now "owns" it.
					m_world->addEntity(box)->removeReference();
				} 

			}
			else
			{
				// Fixed pilars of random size
				hkVector4 size;
				randgen.getRandomVector11(size);
				size.setAbs4( size );
				hkVector4 minSize; minSize.setAll3(0.5f);
				size.add4(minSize);
				size(1) = 2.5f;

				// Random position
				hkVector4 position;
				randgen.getRandomVector11( position );
				position(0) *= 25; position(2) *= 25; position(1) = 0;

				{ 
					// To illustrate using the shape, create a rigid body by first defining a template.
					hkpRigidBodyCinfo rci;
					
					rci.m_shape = new hkpBoxShape( size );
					rci.m_position = position;
					rci.m_friction = 0.1f;
					rci.m_motionType = hkpMotion::MOTION_FIXED;
					

					// Create a rigid body (using the template above).
					hkpRigidBody* pilar = new hkpRigidBody(rci);

					// Remove reference since the body now "owns" the shape.
					rci.m_shape->removeReference();

					pilar->addProperty(HK_PROPERTY_DEBUG_DISPLAY_COLOR, int(hkColor::DARKGREEN)); 

					// Finally add body so we can see it, and remove reference since the world now "owns" it.
					m_world->addEntity(pilar);

					pilar->removeReference();
				} 
			}
		}
	}

	//	Create a character rigid body
	{
	
		// Construct a shape
		hkVector4 vertexA(0.4f,0,0);
		hkVector4 vertexB(-0.4f,0,0);		

		// Create a capsule to represent the character standing
		hkpShape* capsule = new hkpCapsuleShape(vertexA, vertexB, 0.6f);
		

		// Construct a character rigid body
		hkpCharacterRigidBodyCinfo info;
		info.m_mass = 100.0f;
		info.m_shape = capsule;
		info.m_maxForce = 1000.0f;
		info.m_up = UP;
		info.m_position.set(32.0f, 3.0f, 10.0f);
		info.m_maxSlope = HK_REAL_PI/2.0f;	// Only vertical plane is too steep


		m_characterRigidBody = new hkpCharacterRigidBody( info );
		m_world->addEntity( m_characterRigidBody->getRigidBody() );

		capsule->removeReference();

	}
	
	// Create the character state machine and context
	{
		hkpCharacterState* state;
		hkpCharacterStateManager* manager = new hkpCharacterStateManager();

		state = new hkpCharacterStateOnGround();
		manager->registerState( state,	HK_CHARACTER_ON_GROUND);
		state->removeReference();

		state = new hkpCharacterStateInAir();
		manager->registerState( state,	HK_CHARACTER_IN_AIR);
		state->removeReference();

		state = new hkpCharacterStateJumping();
		manager->registerState( state,	HK_CHARACTER_JUMPING);
		state->removeReference();

		state = new hkpCharacterStateClimbing();
		manager->registerState( state,	HK_CHARACTER_CLIMBING);
		state->removeReference();

		m_characterContext = new hkpCharacterContext(manager, HK_CHARACTER_IN_AIR);	
		manager->removeReference();			

		// Set new filter parameters for final output velocity filtering
		// Smoother interactions with small dynamic boxes
		m_characterContext->setCharacterType(hkpCharacterContext::HK_CHARACTER_RIGIDBODY);
		m_characterContext->setFilterParameters(0.9f,12.0f,200.0f);
	}

	// Initialize hkpSurfaceInfo of ground from previous frame
	// Specific case (character is in the air, UP is Y)
	m_previousGround = new hkpSurfaceInfo(UP,hkVector4::getZero(),hkpSurfaceInfo::UNSUPPORTED);
	m_framesInAir = 0;
	
	// Current camera angle about up
	m_currentAngle = 0.0f;

	// Init actual time
	m_time = 0.0f;

	// Init rigid body normal
	m_rigidBodyNormal = UP;

	m_world->unlock();
}
示例#17
0
/*
**
** void init_search_pop(EVOLDATA ev, MATRIX fSearchPop, MATRIX fDC, MATRIX fLC)
**
** Initializes the search population with linearly feasible values.
** Asks the user for input if feasible values cannot be generated
** after NTRIES times.
**
** EVOLDATA	ev			- the main EVOLDATA block
** MATRIX	fSearchPop	- The search population matrix to be filled in
** MATRIX	fDC			- the domain constraint matrix
** MATRIX	fLC			- the linear constraints (inequalities) matrix
**
*/
void
init_search_pop(EVOLDATA ev, MATRIX fSearchPop, MATRIX fDC, MATRIX fLC)
{

	int iFlag, iDCFlag;
	int	iPcount = 0;
	int	iTries = 1;
	int i, j, k, iNumCopies;
	char ch;



	/***************************************************/
	/* SINGLE point initalization                      */
	/***************************************************/
	if (ev.iSearchInitType == SINGLE)
	{
		iFlag = FALSE; iTries = 1;
		while ((iFlag == FALSE) && (iTries <= NTRIES))
		{			
			/* generate random numbers based on the domain constraints */
			for (j=1; j<=ev.iNumVars; j++)
			{
				iDCFlag = FALSE;
				/* check if there is a DC for the variable */
				for (k=1; k<=ev.iNumDC; k++)
					if (j==(int)fDC[k][2])
					{
						fSearchPop[1][j] = randgen(fDC[k][1], fDC[k][3]);
						iDCFlag = TRUE;
					}
				
				/* if no DC, generate values between limits */
				if (iDCFlag == FALSE)
					fSearchPop[1][j] = randgen(MINNUM, MAXNUM);
				
			} /* end of j loop*/

			/* now, check for feasibility wrt. linear inequalities */
			iFlag = check_LC(ev, fSearchPop[1], fLC, fDC);
			iTries++;
		} /* end of while */
		
		/* if generation failed after NTRIES times, ask user for input */
		if (iTries > NTRIES)
		{
			printf("\nSearch Population : Single Point Initialization.\n");		
			printf("Couldn't find a feasible vector in %d tries.\n",				
						NTRIES);
			iFlag = FALSE;
			while (iFlag == FALSE)
			{
				ask_user(fSearchPop[1], ev.iNumVars);
				iFlag = check_LC(ev, fSearchPop[1], fLC, fDC);
			};
		};
		
		/*
		** now, we've got a valid vector.  Copy it into the entire
		** search population.
		*/
		for (i=2; i<=ev.iSearchPopSize; i++)
			for (j=1; j<=ev.iNumVars; j++)
				fSearchPop[i][j] = fSearchPop[1][j];
	} /* end of if SINGLE */
	
	else
	
	/***************************************************/
	/* MULTIPLE point initalization                    */
	/***************************************************/
	{	
		iPcount = 1;
		while (iPcount<=ev.iSearchPopSize)
		{
			iFlag = FALSE; iTries = 1;
			while ((iFlag == FALSE) && (iTries <= NTRIES))
			{
				/* generate random numbers based on the domain constraints */
				for (j=1; j<=ev.iNumVars; j++)
				{
				iDCFlag = FALSE;
				/* check if there is a DC for the variable */
				for (k=1; k<=ev.iNumDC; k++)
					if (j==(int)fDC[k][2])
					{
						fSearchPop[iPcount][j] = randgen(fDC[k][1], fDC[k][3]);
						iDCFlag = TRUE;
					}
				
				/* if no DC, generate values between limits */
				if (iDCFlag == FALSE)
					fSearchPop[iPcount][j] = randgen(MINNUM, MAXNUM);
					
				} /* end of j loop*/
				/* now, check for feasibility wrt. linear inequalities */
				iFlag = check_LC(ev, fSearchPop[iPcount], fLC, fDC);
				iTries++;
			} /* end of while */
			/* if we got a valid vector, fine :) otherwise, beg user :( */
			if (iFlag == TRUE)
				iPcount++;
			else
			/* if generation failed after NTRIES times, ask user for input */
			if (iTries > NTRIES)
			{
				printf("\nSearch Population : Multiple Point Initialization.\n");		
				printf("Couldn't find a feasible vector in %d tries.\n",				
							NTRIES);
				iFlag = FALSE;
				while (iFlag == FALSE)
				{
					ask_user(fSearchPop[iPcount], ev.iNumVars);
					iFlag = check_LC(ev, fSearchPop[iPcount], fLC, fDC);
				};
				/* ask if user wishes to duplicate */
				printf("Valid vector: Duplicate? (Y/N) :");
				fflush(stdin); ch = getchar();
				if ((ch == 'y') || (ch == 'Y'))
				{
					iNumCopies = 0; /* make sure user inputs value */

					do {
						printf("\nNo of copies (1 to %d) : ",
							ev.iSearchPopSize - iPcount+1);					
						scanf_s("%d", &iNumCopies);
					} while ((iNumCopies < 1) ||
					         (iNumCopies > (ev.iSearchPopSize-iPcount+1)));
					/* END of while input validation */
					
					/* now, copy vectors till iNumCopies */
					for (i=1; i<iNumCopies; i++)
					{
						for (j=1; j<=ev.iNumVars; j++)
						{
							fSearchPop[iPcount+1][j] = fSearchPop[iPcount][j];
						}
					iPcount++;
					}
					iPcount++;

				} /* END of block where user requests duplication */
			}; /* END of if tries exhausted */
		}; /* END of iPcount <= iSearchPopSize */
	} /* end of MULTIPLE point initialization */
}
示例#18
0
extern "C" LEVMARDLL_API void StochFit(BoxReflSettings* InitStruct, double parameters[], double covararray[], int paramsize, 
			double info[], double ParamArray[], double chisquarearray[], int* paramarraysize)
{
	FastReflcalc Refl;
	Refl.init(InitStruct);
	double* Reflectivity = InitStruct->Refl;
	int QSize = InitStruct->QPoints;
	double* parampercs = InitStruct->ParamPercs;

	//Setup the fit
	double opts[LM_OPTS_SZ];
	opts[0]=LM_INIT_MU; opts[1]=1E-15; opts[2]=1E-15; opts[3]=1E-20;
	opts[4]=-LM_DIFF_DELTA; // relevant only if the finite difference jacobian version is used 
	
	//Allocate a dummy array - Our real calculation is done in Refl.objective
	double* xvec = new double[InitStruct->QPoints] ;
	for(int i = 0; i < InitStruct->QPoints; i++)
	{
		xvec[i] = 0;
	}

	//Copy starting solution
	double* origguess = new double[paramsize];
	memcpy(origguess, parameters, sizeof(double)*paramsize);

	if(InitStruct->OneSigma)
		Refl.mkdensityonesigma(parameters, paramsize);
	else
		Refl.mkdensity(parameters, paramsize);

	Refl.myrfdispatch();

	double bestchisquare = 0;
	for(int i = 0; i < InitStruct->QPoints; i++)
	{
		bestchisquare += (log(Refl.reflpt[i])-log(Reflectivity[i]))*(log(Refl.reflpt[i])-log(Reflectivity[i]));
	}
	
	double tempinfoarray[9];
	tempinfoarray[1] = bestchisquare;
	double* tempcovararray = new double[paramsize*paramsize];
	memset(tempcovararray,0.0, sizeof(double)*paramsize*paramsize);
	ParameterContainer original(parameters, tempcovararray, paramsize,InitStruct->OneSigma,
		tempinfoarray, parampercs[6]);
	delete[] tempcovararray;

	vector<ParameterContainer> temp;
	temp.reserve(6000);

	omp_set_num_threads(omp_get_num_procs());

	#pragma omp parallel
	{
		FastReflcalc locRefl;
		locRefl.init(InitStruct);

		//Initialize random number generator
		int seed = time_seed();
		CRandomMersenne randgen(time_seed()+omp_get_thread_num());

		ParameterContainer localanswer;
		double locparameters[20];
		double locbestchisquare = bestchisquare;
		double bestparam[20];
		int vecsize = 1000;
		int veccount = 0;
		ParameterContainer* vec = (ParameterContainer*)malloc(vecsize*sizeof(ParameterContainer));
		
		double locinfo[9];

		//Allocate workspace - these will be private to each thread

		double* work, *covar;
		work=(double*)malloc((LM_DIF_WORKSZ(paramsize, QSize)+paramsize*QSize)*sizeof(double));
		covar=work+LM_DIF_WORKSZ(paramsize, QSize);


		#pragma omp for schedule(runtime)
		for(int i = 0; i < InitStruct->Iterations;i++) 
		{
			locparameters[0] = randgen.IRandom(origguess[0]*parampercs[4], origguess[0]*parampercs[5]);
			for(int k = 0; k< InitStruct->Boxes; k++)
			{
				if(InitStruct->OneSigma)
				{
					locparameters[2*k+1] = randgen.IRandom(origguess[2*k+1]*parampercs[0], origguess[2*k+1]*parampercs[1]);
					locparameters[2*k+2] = randgen.IRandom(origguess[2*k+2]*parampercs[2], origguess[2*k+2]*parampercs[3]);
				}
				else
				{
					locparameters[3*k+1] = randgen.IRandom(origguess[3*k+1]*parampercs[0], origguess[3*k+1]*parampercs[1]);
					locparameters[3*k+2] = randgen.IRandom(origguess[3*k+2]*parampercs[2], origguess[3*k+2]*parampercs[3]);
					locparameters[3*k+3] = randgen.IRandom(origguess[3*k+3]*parampercs[4], origguess[3*k+3]*parampercs[5]);
				}
			}

			locparameters[paramsize-1] = origguess[paramsize-1];
			
			
			if(InitStruct->UL == NULL)
				dlevmar_dif(locRefl.objective, locparameters, xvec,  paramsize, InitStruct->QPoints, 500, opts, locinfo, work,covar,(void*)(&locRefl)); 
			else
				dlevmar_bc_dif(locRefl.objective, locparameters, xvec, paramsize, InitStruct->QPoints, InitStruct->LL, InitStruct->UL,
					500, opts, locinfo, work,covar,(void*)(&locRefl)); 
			
			localanswer.SetContainer(locparameters,covar,paramsize,InitStruct->OneSigma,locinfo, parampercs[6]);

			if(locinfo[1] < bestchisquare && localanswer.IsReasonable())
			{
				//Resize the private arrays if we need the space
				if(veccount+2 == vecsize)
				{
							vecsize += 1000;
							vec = (ParameterContainer*)realloc(vec,vecsize*sizeof(ParameterContainer));
				}

				bool unique = true;
				int arraysize = veccount;

				//Check if the answer already exists
				for(int i = 0; i < arraysize; i++)
				{
					if(localanswer == vec[i])
					{
						unique = false; 
						i = arraysize;
					}
				}
				//If the answer is unique add it to our set of answers
				if(unique)
				{
					vec[veccount] = localanswer;
					veccount++;
				}
			}
		}
		#pragma omp critical (AddVecs)
		{
			for(int i = 0; i < veccount; i++)
			{
				temp.push_back(vec[i]);
			}
		}
		free(vec);
		free(work);
	}
	//
	delete[] xvec;
	delete[] origguess;

	//Sort the answers
	//Get the total number of answers
	temp.push_back(original);

	vector<ParameterContainer> allsolutions;
	allsolutions.reserve(6000);

	int tempsize = temp.size();
	allsolutions.push_back(temp[0]);

	for(int i = 1; i < tempsize; i++)
	{
		int allsolutionssize = allsolutions.size();
		for(int j = 0; j < allsolutionssize;j++)
			{
				if(temp[i] == allsolutions[j])
				{
					break;
				}
				if(j == allsolutionssize-1)
				{
					allsolutions.push_back(temp[i]);
				}
			}
	}

	if(allsolutions.size() > 0)
	{
		sort(allsolutions.begin(), allsolutions.end());
	}

	for(int i = 0; i < allsolutions.size() && i < 1000 && allsolutions.size() > 0; i++)
	{
		for(int j = 0; j < paramsize; j++)
		{
			ParamArray[(i)*paramsize+j] = (allsolutions.at(i).GetParamArray())[j];
			covararray[(i)*paramsize+j] = (allsolutions.at(i).GetCovarArray())[j];
		}

		memcpy(info, allsolutions.at(i).GetInfoArray(), 9* sizeof(double));
		info += 9;

		chisquarearray[i] = (allsolutions.at(i).GetScore());
	}
	*paramarraysize = min(allsolutions.size(),999);
}
示例#19
0
/*
**
** void nu_mutate(EVOLDATA ev, VECTOR fV, int iIndex,
**						MATRIX fDC, MATRIX fLC, long lNumEvals, int iPopSize)
**
** Non-uniform mutation operator - single parent, single offspring
**
**
*/
void nu_mutate(EVOLDATA ev, VECTOR fV, int iIndex,
	MATRIX fDC, MATRIX fLC, long lNumEvals, int iPopSize)
{
	int i, j, iFlag;
	float fLlim, fUlim, fSum, fNewLimit, fRandVal, fFactor;
	int iNewt, iNewT, iExponent;

	iFlag = GENOCOP_FALSE;
	/* see if the chosen variable has any Domain Constraints */
	for (i = 1; i <= ev.iNumDC; i++)
	{
		if ((int) fDC[i][2] == iIndex)
		{
			fUlim = fDC[i][3];
			fLlim = fDC[i][1];
			iFlag = GENOCOP_TRUE;
		}
	}
	if (iFlag == GENOCOP_FALSE)
	{
		fUlim = GENOCOP_MAXNUM;
		fLlim = GENOCOP_MINNUM;
	}

	/* now, get new limit from linear constraints */
	/* for this, first substitute all other variables */
	/* keeping in mind that the function is stated as f[x] >= 0 */

	for (i = 1; i <= ev.iNumLC; i++)
	{
		/*
		** CHECK LIMITS ONLY IF COEFF. OF VARIABLE IS NON-ZERO
		**
		*/
		if (fLC[i][iIndex] != 0.0)
		{
			fSum = 0.0;
			for (j = 1; j <= ev.iNumVars; j++)
			if (j != iIndex)
				fSum = fSum + fV[j] * fLC[i][j];
			fSum = fSum + fLC[i][ev.iNumVars + 1];	/* constant term */
			/* now, function is fSum+fV[iIndex]*fLC[i][iIndex] >= 0 */
			/* this is the new lower limit, after comparison */
			fNewLimit = (-1 * fSum) / fLC[i][iIndex];
			/* now, if the coeff. was NEGATIVE, the inequality is CHANGED */

			/* while carrying it over, and it becomes a possible new */
			/* LOWER limit */
			if (fLC[i][iIndex] > 0.0)	/* CHANGE SIGN IF NEGATIVE */
			{
				if (fNewLimit > fLlim)
					fLlim = fNewLimit;
			}
			else
			{
				if (fNewLimit < fUlim)
					fUlim = fNewLimit;
			}
		}

	}

	fRandVal = randgen(0.0, 1.0);
	/* pick either the max or min. limit */
	if (fRandVal < 0.5)		/* lower */
	{
		iNewt = (int) (lNumEvals / iPopSize);
		iNewT = (int) (ev.lTotEvals / iPopSize);
		iExponent = (int) (6 * randgen(0.0, 1.0)) + 1;
		fRandVal = randgen(0.0, 1.0);


		/* NOTE: The three statements below are alternate techniques  */
		/*       Suitability seems to vary according to the objective */
		/*       function.  Experiment by commenting in/out           */

		/*fFactor = power((1.0F - (float)(iNewt/iNewT)), iExponent) *
					randgen(0.0, 1.0);*/

		/*fFactor = power(0.5, iExponent)*randgen(0.0, 1.0);*/

		fFactor = power(0.2, 6)*randgen(0.0, 1.0);

		if (fFactor < .00001) fFactor = 0.00001;
		fFactor = fFactor * (fV[iIndex] - fLlim);
		fV[iIndex] = fV[iIndex] - fFactor;
	}
	else
	{
		iNewt = (int) lNumEvals / iPopSize;
		iNewT = (int) ev.lTotEvals / iPopSize;
		iExponent = (int) (6 * randgen(0.0, 1.0)) + 1;
		fRandVal = randgen(0.0, 1.0);

		/* NOTE: The three statements below are alternate techniques  */
		/*       Suitability seems to vary according to the objective */
		/*       function.  Experiment by commenting in/out           */

		/*fFactor = power((1.0F - (float)(iNewt/iNewT)), iExponent) *
					randgen(0.0, 1.0);*/

		/*fFactor = power(0.5, iExponent)*randgen(0.0, 1.0);*/

		fFactor = power(0.2, 6)*randgen(0.0, 1.0);


		if (fFactor < .00001) fFactor = 0.00001;
		fFactor = fFactor * (fUlim - fV[iIndex]);
		fV[iIndex] = fV[iIndex] + fFactor;
	}


}