Пример #1
0
float randNormal()
{
    static float y1, y2;
    
    // This generates 2 numbers at a time, so 
    // alternate between generating a new one and
    // just returning the last one
    static bool doGen = true;
    if (!doGen)
    {
        // return the other number we generated
        // last time
        return y2;        
    }
    else
    {        
        float x1, x2, w;

        // reject points outside the unit circle
        do {
            x1 = (2.0f * randUniform()) - 1.0;
            x2 = (2.0f * randUniform()) - 1.0;
            w = x1*x1 + x2*x2;        
        } while (w >= 1.0 );
        
        w = sqrt( (-2.0 * logf(w)) / w );
        y1 = x1 * w;
        y2 = x2 * w;

        return y1;
    }
}
static void doLoop(bool warmup, int pgm, uint32_t passCount) {
    if (warmup) {
        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        ptSwap();
        glFinish();
        return;
    }

    startTimer();
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    for (uint32_t ct=0; ct < passCount; ct++) {
        int loc = glGetUniformLocation(pgm, "u_texOff");
        glUniform2f(loc, ((float)ct) / passCount, ((float)ct) / 2.f / passCount);

        randUniform(pgm, "u_color");
        randUniform(pgm, "u_0");
        randUniform(pgm, "u_1");
        randUniform(pgm, "u_2");
        randUniform(pgm, "u_3");
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }
    ptSwap();
    glFinish();
    endTimer(passCount);
}
Пример #3
0
double nucmath::getRandom(double start, double end)
{
#ifdef __MINGW32__
	return start + static_cast<double>(rand()) / static_cast<float>(RAND_MAX / (end - start));
#else
	std::uniform_real_distribution<double> randUniform(0.0, 1.0);
	return start + randUniform(rnd2)*abs(end - start);
#endif
}
void VoxSprite::chooseRandomDir()
{
    int d = int( randUniform() * 5.0 );
    
    m_angle = d * 90.0;
    m_timeout = randNormal( 4.0, 1.0 );
}
void ParticleBuff::emitRadial( ParticleType ptype, float x, float y, float radius )
{
	Particle *p = emitPart( ptype );
	if (!p) return; // Buff full
	
	// set up general stuff
	const float initialVel = 50.0;
	p->x = x + randNormal() * radius;
	p->y = y + randNormal() * radius;
	p->maxAge = 3.0 + randNormal();
	
	if ((ptype==Particle_RIPPLE) || (ptype==Particle_SMOKE))
	{
		p->angle = 0.0;
		p->dx = 0.0;
		p->dy = 0.0;
	}
	else if (ptype == Particle_DOT)
	{
		p->dx = randNormal() * initialVel;
		p->dy = (1.0+randNormal()) * initialVel;
	}
	else
	{
		p->angle = randUniform() * 360.0;
		p->dx = randNormal() * initialVel;
		p->dy = randNormal() * initialVel;
	}
	p->age = 0;
}
Пример #6
0
void Facility::dynamics(double beta, int timeStep)
{
	double probability = 1 - pow(1 - beta, countInf());
	std::vector<double> probs = { probability, (1 - probability) };

	for (Agent* a : agents)
	{
		if ((*a).getState() == 0) {	//sus to exp
			if (randProb(probs) == 0) {
				(*a).setState(1);
			}
		}
		else if ((*a).getState() == 1) {	//exp to inf
			if ((*a).getEI() == -1) {
				if (inc_dist == 1 || inc_dist == 0) {		//uniform or single value
					(*a).setEI(timeStep + ceil(randUniform()*(upper_inc - lower_inc)) + lower_inc);
				}
				else if (inc_dist == 2) {		//triangular
					(*a).setEI(timeStep + ceil(randTriangle()*(upper_inc - lower_inc)) + lower_inc);
				}
			}
			else if (timeStep == (*a).getEI()) {
				(*a).setState(2);
				(*a).setEI(-1);
			}
		}
		else if ((*a).getState() == 2) {	//inf to sus
			if ((*a).getIS() == -1) {
				if (inf_dist == 1 || inf_dist == 0) {		//uniform or single value
					(*a).setIS(timeStep + ceil(randUniform()*(upper_inf - lower_inf)) + lower_inf);
				}
				else if (inf_dist == 2) {		//triangular
					(*a).setIS(timeStep + ceil(randTriangle()*(upper_inf - lower_inf)) + lower_inf);
				}
			}
			else if (timeStep == (*a).getIS()) {
				(*a).setState(0);
				(*a).setIS(-1);
			}
		}
	}

}
Пример #7
0
void Facility::reset() {
	agents.clear();
	//reinitialize agents
	for (int i = 0; i < startS; i++) {
		Agent * a = new Agent();
		(*a).setState(0);
		(*a).setEI(-1);
		(*a).setIS(-1);
		(*a).setDischarge(LOS());
		(*a).setFacility(facility);
		agents.push_back(a);
	}
	for (int i = 0; i < startE; i++) {
		Agent * a = new Agent();
		(*a).setState(1);
		if (inc_dist == 1 || inc_dist == 0) {		//uniform or single value
			(*a).setEI(ceil(randUniform()*(upper_inc - lower_inc)) + lower_inc);
		}
		else if (inc_dist == 2) {	//triangular
			(*a).setEI(ceil(randTriangle()*(upper_inc - lower_inc)) + lower_inc);
		}
		(*a).setIS(-1);
		(*a).setDischarge(LOS());
		(*a).setFacility(facility);
		agents.push_back(a);
	}
	for (int i = 0; i < startI; i++) {
		Agent * a = new Agent();
		(*a).setState(2);
		(*a).setEI(-1);
		if (inf_dist == 1 || inf_dist == 0) {		//uniform or single value
			(*a).setIS(ceil(randUniform()*(upper_inf - lower_inf)) + lower_inf);
		}
		else if (inf_dist == 2) {	//triangular
			(*a).setIS(ceil(randTriangle()*(upper_inf - lower_inf)) + lower_inf);
		}
		(*a).setDischarge(LOS());
		(*a).setFacility(facility);
		agents.push_back(a);
	}
}
Пример #8
0
int Facility::randProb(std::vector<double> probs)
{
	double currProb = probs[0];
	double rand = randUniform();
	for (int i = 0; i<(probs.size() - 1); i++) {
		if (rand<currProb) {
			return i;				//return index of drawn probability
		}
		currProb = currProb + probs[i + 1];
	}
	return probs.size() - 1;
}
void ParticleBuff::emitRadial( ParticleType ptype, float x, float y, float radius )
{
	Particle *p = emitPart( ptype );
	if (!p) return; // Buff full
	
	// set up general stuff
	const float initialVel = 50.0;
	p->x = x + randNormal() * radius;
	p->y = y + randNormal() * radius;
	p->maxAge = 3.0 + randNormal();

	//p->r = 1.0; p->g = 1.0; p->b = 1.0;
	float t = randUniform();
	float rA = 166/255.0; float gA = 202/255.0; float bA = 222/255.0;
	float rB = 31/255.0; float gB = 45/255.0; float bB = 227/255.0;
	p->r = (rA*t) + (rB*(1.0-t));
	p->g = (gA*t) + (gB*(1.0-t));
	p->b = (bA*t) + (bB*(1.0-t));
	
	if ((ptype==Particle_RING) || (ptype==Particle_SMOKE))
	{
		p->angle = randUniform( 0.0, 360.0);		
		p->dx = 0.0;
		p->dy = 0.0;
	}
	else if (ptype == Particle_DOT)
	{
		p->dx = randNormal() * initialVel;
		p->dy = (1.0+randNormal()) * initialVel;
	}
	else
	{
		p->angle = randUniform() * 360.0;
		p->dx = randNormal() * initialVel;
		p->dy = randNormal() * initialVel;
	}
	p->age = 0;
}
Пример #10
0
Facility::Facility(int facil, std::string in, boost::variate_generator< boost::mt19937&, boost::random::triangle_distribution < > > * triangle, boost::variate_generator< boost::mt19937&, boost::random::uniform_real_distribution < > > * uniform, int incdist, double upinc, double lowinc, int infdist, double upinf, double lowinf)
{
	facility = facil;
	std::string input[11];
	int i = 0;
	std::stringstream ssin(in);
	while (ssin.good() && i < 11) {
		ssin >> input[i];
		++i;
	}

	name = input[0];
	subfacil = stoi(input[1]);
	startS = stoi(input[2]);
	startE = stoi(input[3]);
	startI = stoi(input[4]);
	bed_size = stoi(input[5]);
	prev = stod(input[6]);
	inc = stod(input[7]);
	LOS_mean = stod(input[8]);
	LOS_dev = stod(input[9]);
	LOS_dist = stoi(input[10]);

	RNGpoint = uniform;
	triangleRNGpoint = triangle;

	genpoint = new boost::mt19937 (time(0));	//create RNG
	boost::random::lognormal_distribution< > lognormalDistribution(LOS_mean, LOS_dev);
	boost::random::normal_distribution< > normalDistribution(LOS_mean, LOS_dev);
	lognormRNGpoint = new boost::variate_generator< boost::mt19937&, boost::random::lognormal_distribution < > >(*genpoint, lognormalDistribution);
	normalRNGpoint = new boost::variate_generator< boost::mt19937&, boost::random::normal_distribution < > >(*genpoint, normalDistribution);

	inf_dist = infdist;
	inc_dist = incdist;
	lower_inf = lowinf;
	upper_inf = upinf;
	lower_inc = lowinc;
	upper_inc = upinc;


	//initialize agents
	for (int i = 0; i < startS; i++) {
		Agent * a = new Agent();
		(*a).setState(0);
		(*a).setEI(-1);
		(*a).setIS(-1);
		(*a).setDischarge(LOS());
		(*a).setFacility(facility);
		agents.push_back(a);
	}
	for (int i = 0; i < startE; i++) {
		Agent * a = new Agent();
		(*a).setState(1);
		if (inc_dist == 1 || inc_dist == 0) {		//uniform or single value
			(*a).setEI(ceil(randUniform()*(upper_inc - lower_inc)) + lower_inc);
		}
		else if (inc_dist == 2) {	//triangular
			(*a).setEI(ceil(randTriangle()*(upper_inc - lower_inc)) + lower_inc);
		}
		(*a).setIS(-1);
		(*a).setDischarge(LOS());
		(*a).setFacility(facility);
		agents.push_back(a);
	}
	for (int i = 0; i < startI; i++) {
		Agent * a = new Agent();
		(*a).setState(2);
		(*a).setEI(-1);
		if (inf_dist == 1 || inf_dist == 0) {		//uniform or single value
			(*a).setIS(ceil(randUniform()*(upper_inf - lower_inf)) + lower_inf);
		}
		else if (inf_dist == 2) {	//triangular
			(*a).setIS(ceil(randTriangle()*(upper_inf - lower_inf)) + lower_inf);
		}
		(*a).setDischarge(LOS());
		(*a).setFacility(facility);
		agents.push_back(a);
	} 

}
// fill up vertex buffer from part list
void ParticleBuff::updateParts( float dt )
{
	for (size_t i=0; i < m_numParts; ++i)
	{
		Particle &p = m_parts[i];
		
		float lasty = p.y;
	
		p.x = p.x + p.dx * dt;
		p.y = p.y + p.dy * dt;
		
		// Hack -- spawn a ripple if we cross the water surface
		if ((lasty >= 100) && (p.y <= 100))
		{
			emitRadial( Particle_RIPPLE, p.x, p.y + randUniform( -3.0, 3.0), 0.0 );
			p.age = p.maxAge;
		}
		
		// update age
		p.age += dt;
	
		float life = p.age / p.maxAge;
		
		switch (p.ptype)
		{
			case Particle_DOT:
			case Particle_DOT2:
				// Apply gravity
				p.dy = p.dy + (-100*dt);
				
				// update size
				p.sx = p.sy = 10.0 * (1.0 - life);
				break;
				
			case Particle_SMOKE:
				// grow and fade
				p.sx = 30.0 + 30 * life;
				p.sy = 30.0 + 30 * life;
				break;
				
			case Particle_RIPPLE:
				// grow and fade
				p.sx = 10.0 + 50 * life;
				p.sy = 10.0 + 50 * life;
				break;
		}
		

	}
	
	// kill off old particles
	for (int i = m_numParts-1; i >=0; i--)
	{
		// did this particle age out?
		if (m_parts[i].age > m_parts[i].maxAge)
		{
			// If this is not the last particle,
			// swap the last one into its place
			if (i<m_numParts-1)
			{
				m_parts[i] = m_parts[m_numParts-1];
			}
			m_numParts--;
		}
	}
}
Пример #12
0
void TestApp::SceneCollect::init()
{
    // Set up luddite stuff
    luddite::RenderDeviceGL *renderDeviceGL = new luddite::RenderDeviceGL();
    m_renderDevice = renderDeviceGL;
    
    // Setup camera (TODO: do this differently)
    glhPerspectivef2( renderDeviceGL->matProjection, 20.0, 800.0/600.0, 1.0, 500.0 );
    matrix4x4f cameraXlate, cameraRot;
    cameraXlate.Translate(0.0, -4, -15.0);
    cameraRot.RotateX( 15.0 * (M_PI/180.0) );
    renderDeviceGL->matBaseModelView = cameraXlate * cameraRot;
    
    // Initialize shader DB
    m_mtlDB = new luddite::MaterialDB( );
    m_mtlDB->initShaderDB();
    
    // Add material def files
    m_mtlDB->addMaterialDefs("CollectGame.material.xml" );
    
    luddite::Material *mtl  = m_mtlDB->getNamedMaterial( m_renderDevice, "mtl.environment" );
    
    // Build scene graph
    m_worldRoot = new luddite::SceneNode( "worldRoot" );

    // Load the ground plane obj file in the center.
    m_groundPlane = scene_objfile_named( "grid10x10.obj", m_renderDevice, m_mtlDB );
    m_worldRoot->addChild( m_groundPlane );

    // Load the player mesh
    m_player = scene_objfile_named( "player.obj", m_renderDevice, m_mtlDB );
    m_worldRoot->addChild( m_player );

    // Load the trees
    luddite::SceneNode *tree = scene_objfile_named("tree_fir.obj", m_renderDevice, m_mtlDB );
    tree->m_pos = vec3f( 2.0, 0.0, 1.5 );
    m_worldRoot->addChild( tree );
    
    m_trees.push_back(tree);
    
    // Add tree instances
    for (int i=0; i <20; i++)
    {
        luddite::SceneNode *treeInst = tree->makeInstance();
        
        // Generate a random position for the tree, outside the center of the
        // map (TODO: also don't overlap other trees)
        do {
            vec3f treePos = vec3f( randUniform(-10.0, 10.0), 0.0, randUniform(-10.0, 10.0) );
            treeInst->m_pos = treePos;
        } while (prmath::LengthSquared(treeInst->m_pos) < 1.0 );

        m_worldRoot->addChild( treeInst );
        m_trees.push_back( treeInst );
    }
    
    // FIXME.. this is temporary, shouldn't need to do this (and we shouldn't
    // upload all the shaders, only used ones)
    m_mtlDB->useAllShaders( m_renderDevice );
    
    // Finally, create scene for our node graph
    m_scene = new luddite::Scene( m_worldRoot );


}
Пример #13
0
static void generate(const PARAMS *p,DATA *d)
{
	double dTheta,dSpaceTheta,dSpaceZ,dDepth,dSpaceXY;
	int i,iR,iZ,iX,iY;

	randSeedGenerator(time(NULL) % getpid() + getppid());

	i = 0;

	if (p->nStuck > 0) {
		printf("Generating %i stuck particle%s in %ix(%i/%i) grid.\n",
			   p->nStuck,p->nStuck == 1 ? "" : "s",
			   p->nStuckR,p->nStuckZ,p->nStuckZ > 1 ? p->nStuckZ - 1 : 1);

		dTheta = TWO_PI/p->nStuckR;

		printf("Stuck-particle cell dimensions: %g cm x %g cm (angular increment = %g deg).\n",
			   100.0*p->dStuckR*AU,100.0*p->dStuckZ*AU,dTheta*180.0/PI);

		for (iZ=0;iZ<p->nStuckZ;iZ++)
			for (iR=0;iR<p->nStuckR;iR++) {
				if (p->nStuckZ > 1 && iR % 2 == 1 && iZ == 0)
					continue; /* to stagger the grid */
				do {
					d[i].radius = p->dStuckAvg + gaussian(p->dStuckDev,p->dCutoff);
					} while (d[i].radius <= 0.0); /* reject non-physical values */
				dSpaceTheta = (p->dStuckR - 2.0*d[i].radius)/p->dCylRad; /* available longitudinal space in cell */
				if (dSpaceTheta < 0.0)
					dSpaceTheta = 0.0;
				dSpaceZ = p->dStuckZ - 2.0*d[i].radius; /* available vertical space in cell */
				if (dSpaceZ < 0.0)
					dSpaceZ = 0.0;
				dDepth = 2.0*(0.5 - (p->dDepthAvg + gaussian(p->dDepthDev,p->dCutoff)))*d[i].radius;
				d[i].pos[0] = (p->dCylRad - dDepth)*cos(dTheta*iR + (randUniform() - 0.5)*dSpaceTheta);
				d[i].pos[1] = (p->dCylRad - dDepth)*sin(dTheta*iR + (randUniform() - 0.5)*dSpaceTheta);
				d[i].pos[2] = -0.5*p->dCylLen + ((double) iZ + 0.5)*p->dStuckZ + (randUniform() - 0.5)*dSpaceZ - (p->nStuckZ > 1 ? (iR % 2)*0.5*p->dStuckZ : 0.0);
				++i;
				}
		}

	assert(i == p->nStuck);

	if (p->nFree > 0) {
		printf("Generating %i free particle%s in %ix%ix%i grid.\n",
			   p->nFree,p->nFree == 1 ? "" : "s",
			   p->nFreeXY,p->nFreeXY,p->nFreeZ);

		printf("Free-particle cell dimensions: %g cm x %g cm x %g cm.\n",
			   100.0*p->dFreeXY*AU,100.0*p->dFreeXY*AU,100.0*p->dFreeZ*AU);

		for (iZ=0;iZ<p->nFreeZ;iZ++)
			for (iX=0;iX<p->nFreeXY;iX++)
				for (iY=0;iY<p->nFreeXY;iY++) {
					do {
						do {
							d[i].radius = p->dFreeAvg + gaussian(p->dFreeDev,p->dCutoff);
							} while (d[i].radius <= 0.0);
						dSpaceXY = (p->dFreeXY - 2.0*d[i].radius); /* available xy-space in cell */
						} while (dSpaceXY <= 0.0);
					dSpaceZ = p->dFreeZ - 2.0*d[i].radius; /* available z-space in cell */
					if (dSpaceZ < 0.0)
						dSpaceZ = 0.0;
					d[i].pos[0] = -sqrt(0.5)*p->dCylRad + ((double) iX + 0.5)*p->dFreeXY + (randUniform() - 0.5)*dSpaceXY;
					d[i].pos[1] = -sqrt(0.5)*p->dCylRad + ((double) iY + 0.5)*p->dFreeXY + (randUniform() - 0.5)*dSpaceXY;
					d[i].pos[2] = -0.5*p->dCylLen + ((double) iZ + 0.5)*p->dFreeZ + (randUniform() - 0.5)*dSpaceZ;
					++i;
					}
		}

	assert(i == p->nPart);
	}
void Bonsai::buildAll()
{
	// generate a unique random seed for the whole thing from the name
	DBG::info("Generate planet '%s'\n", m_name );
	int master_seed = 1;
	for (const char *ch=m_name; *ch; ch++)
	{
		master_seed *= (*ch);
	}

	// generate random seeds for each step .. this keeps them
	// somewhat resistant to changes in the algoritms 
	int pally_seed, param_seed, terrain_seed;
	srand( master_seed );
	pally_seed = rand();
	terrain_seed = rand();
	param_seed = rand();
		
	// Make the palette
	m_pally.generate( pally_seed );

	// synthesize the height data
	m_hiteData = new float [ HITE_RES * HITE_RES ];
	m_terrainColor = new GLubyte [ HITE_RES * HITE_RES * 3 ];
	m_terrainNorm = new GLubyte [ HITE_RES * HITE_RES * 3 ];

	// Set up params
	srand( param_seed );
	m_params.offs = randUniform( 0.0, 1000.0 );

	m_params.base = (int)randUniform( 0, NUM_BASE );	
	m_params.base_distAmt = randUniform( 0.0, 0.3 );
	m_params.base_scale = randUniform( 0.3, 1.0 );	

	m_params.baseVeg = (int)randUniform( 0, NUM_BASEVEG );	

	m_params.baseVeg_hite_repeats = (int)randUniform( 1, 5 );		
	m_params.baseVeg_hite_repeats *= m_params.baseVeg_hite_repeats;	

	m_params.patchVeg = (int)randUniform( 0, NUM_PATCHVEG );	
	m_params.patchVeg_scale = randUniform( 1.0, 20.0 );
	m_params.patchVeg_nscale = randUniform( 0.01, 8.0 );
	m_params.patchVeg_nscale *= m_params.patchVeg_nscale;
	m_params.patchMixMineral = (randUniform() > 0.5)?1:0;
	m_params.patchVeg_thresh = randUniform( 0.55, 0.85 );	

	// Decoration
	m_params.deco = (int)randUniform( 0, NUM_DECORATION );	
	m_params.decoLavaScale = randUniform( 1.0, 10.0 );
	m_params.decoLavaWidth = randUniform( 0.01, 0.1 );

	// =============================================

	// build textures
	Luddite::HTexture htexColor;
	Luddite::HTexture htexNorms;	
	

	// check if there is cached image data available		
	htexColor = _checkCachedColorImage( "DIF0", m_terrainColor, HITE_RES);
	if ( (!htexColor.isNull() ) && (_checkCachedHeight( "HITE", m_hiteData, HITE_RES ) ))
	{
		DBG::info( "Land '%s' read cached color and height.\n", m_name );
	}
	else
	{
		// Synthesize
		srand( terrain_seed );

		// step for tuning/debugging quicker
		// step=1 for final quality
		int step = SYNTH_STEP;
		for (int j=0; j < HITE_RES; j += step)
		{
			// status
			progress( "Generating", j, HITE_RES );			

			for (int i=0; i < HITE_RES; i += step )
			{
				float ii = (((float)i / (float)HITE_RES) * 2.0) - 1.0;
				float jj = (((float)j / (float)HITE_RES) * 2.0) - 1.0;

				// synthesize a texel
				size_t ndx = (j*HITE_RES)+i;
				synthesize( ndx, ii, jj );

				for (int sj = 0; sj < step; sj++)
				{
					for(int si=0; si < step; si++)
					{			
						if (si || sj)
						{
							size_t ndx2 = ((j+sj)*HITE_RES)+(i+si);

							m_terrainColor[ndx2 * 3 + 0] = m_terrainColor[ndx * 3 + 0];
							m_terrainColor[ndx2 * 3 + 1] = m_terrainColor[ndx * 3 + 1];
							m_terrainColor[ndx2 * 3 + 2] = m_terrainColor[ndx * 3 + 2];

							m_hiteData[ndx2] = m_hiteData[ndx];

						}
					}
				}
			}
		}

		// Calculate (fake) ambient occlusion
		for (int j=0; j < HITE_RES; j += 1)
		{
			progress( "AmbOccl", j, HITE_RES );

			for (int i=0; i < HITE_RES; i += 1 )
			{
				float ambOccl = 0.0f;
				int c = 0;
				size_t ndx = (j*HITE_RES)+i;

				// TODO: gaussian weight
				for (int ii=-8; ii < 8; ii += 2)
				{
					for (int jj=-8; jj < 8; jj += 2)
					{
						int i2 = i+ii;
						int j2 = j+jj;
						c += 1;
						
						float occl = 0.0;
						if ((i2 >=0) && (i2 < HITE_RES)  &&
							(j2 >=0) && (j2 < HITE_RES) )
						{
							size_t ndx2 = (j2*HITE_RES)+i2;
							occl = m_hiteData[ndx2] - m_hiteData[ndx];							
							occl = fstep( 0.0, 0.015, occl );														
							
							ambOccl += occl;
						}						
					}
				}

				// avg
				ambOccl /= c;
				ambOccl = clamp( 1.0-ambOccl, 0.0, 1.0 );

				// darken color image (dbg replace)
#if 0
				m_terrainColor[ndx * 3 + 0] = (int)(ambOccl * 255);
				m_terrainColor[ndx * 3 + 1] = (int)(ambOccl * 255);
				m_terrainColor[ndx * 3 + 2] = (int)(ambOccl * 255);
#else
				m_terrainColor[ndx * 3 + 0] *= ambOccl;
				m_terrainColor[ndx * 3 + 1] *= ambOccl;
				m_terrainColor[ndx * 3 + 2] *= ambOccl;
#endif

			}
		}
				

		// Cache the height & color data
		SDL_WM_SetCaption( "[Cache Height/Color] LD19 Jovoc - Discovery", NULL );

		_cacheColorImage( "DIF0", m_terrainColor, HITE_RES );
		_cacheHeight( "HITE", m_hiteData, HITE_RES );
	}

	// check if there is cached normal data available
	htexNorms = _checkCachedColorImage( "NRM", m_terrainNorm, HITE_RES);
	if ( !htexNorms.isNull() )
	{
		DBG::info( "Land '%s' read cached normals.\n", m_name );
	}
	else
	{
		// Shitty calc normals -- ideally this should use the
		// height samples to not soften it but for now do it this
		// way cause it's easier/faster
		for (int j=0; j < HITE_RES-1; j++)
		{
			progress( "Calc Normals", j, HITE_RES );

			for (int i=0; i < HITE_RES-1; i++ )
			{
				PVRTVec3 nrm;
				size_t ndx = (j*HITE_RES)+i;
				float a = m_hiteData[ndx];
				float b = m_hiteData[ (j*HITE_RES)+(i+1) ];
				float c = m_hiteData[ ((j+1)*HITE_RES)+i ];

				//float scl = 5.4;
				float scl = 50.0f;
				float dy1 = (b - a) * scl;
				float dy2 = (c - a) * scl;				

				PVRTVec3 n( dy1, dy2, 1.0 - sqrt( dy1*dy1 + dy2*dy2 ) );
				n.normalize();

				m_terrainNorm[ndx * 3 + 0] = (int)((n.x * 128.0) + 128.0);
				m_terrainNorm[ndx * 3 + 1] = (int)((n.y * 128.0) + 128.0);
				m_terrainNorm[ndx * 3 + 2] = (int)((n.z * 128.0) + 128.0);
			}
		}

		// Cache the normal map
		SDL_WM_SetCaption( "[Cache Normals] LD19 Jovoc - Discovery", NULL );
		_cacheColorImage( "NRM", m_terrainNorm, HITE_RES );
	}

	SDL_WM_SetCaption( "LD19 Jovoc - Discovery [Press TAB to ungrab mouse]", NULL );

	// Build texture
	static int treeId = 0;
	
	Luddite::TextureDB *texDB = Luddite::TextureDB::singletonPtr();
	if (htexColor.isNull())
	{
		char s[20];
		sprintf( s, "treeland%d", treeId++);
		htexColor = texDB->buildTextureFromData( s, m_terrainColor, 1024, 1024 );
	}

	if (htexNorms.isNull())
	{
		char s[20];
		sprintf( s, "treenorms%d", treeId++);
		htexNorms = texDB->buildTextureFromData( s, m_terrainNorm, 1024, 1024 );
	}

	// Make a land part
	m_treeLand = new TreeLand( m_hiteData, htexColor, htexNorms );
	m_treeLand->build();
}
Пример #15
0
float randUniform( float minVal, float maxVal )
{
    return minVal + (randUniform() * (maxVal-minVal));    
}