vector3d TerrainColorFractal<TerrainColorAsteroid>::GetColor(const vector3d &p, double height, const vector3d &norm) const
{
	double n = m_invMaxHeight*height/2;

	if (n <= 0.02) {
		const double flatness = pow(p.Dot(norm), 6.0);
		const vector3d color_cliffs = m_rockColor[1];

		double equatorial_desert = (2.0)*(-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) *
			1.0*(2.0)*(1.0-p.y*p.y);

		vector3d col;
		col = interpolate_color(equatorial_desert, m_rockColor[0], m_greyrockColor[3]);
		col = interpolate_color(n, col, vector3d(1.5,1.35,1.3));
		col = interpolate_color(flatness, color_cliffs, col);
		return col;
	} else {
		const double flatness = pow(p.Dot(norm), 6.0);
		const vector3d color_cliffs = m_greyrockColor[1];

		double equatorial_desert = (2.0)*(-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) *
			1.0*(2.0)*(1.0-p.y*p.y);

		vector3d col;
		col = interpolate_color(equatorial_desert, m_greyrockColor[0], m_greyrockColor[2]);
		col = interpolate_color(n, col, m_rockColor[3]);
		col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
}
Пример #2
0
vector3d TerrainColorFractal<TerrainColorBandedRock>::GetColor(const vector3d &p, double height, const vector3d &norm) const
{
	const double flatness = pow(p.Dot(norm), 6.0);
	double n = fabs(noise(vector3d(height*10000.0,0.0,0.0)));
	vector3d col = interpolate_color(n, m_rockColor[0], m_rockColor[1]);
	return interpolate_color(flatness, col, m_rockColor[2]);
}
Пример #3
0
double Ship::AIFaceOrient(const vector3d &dir, const vector3d &updir)
{
	double timeStep = Pi::GetTimeStep();
	matrix4x4d rot; GetRotMatrix(rot);
	double maxAccel = GetShipType().angThrust / GetAngularInertia();		// should probably be in stats anyway
	double frameAccel = maxAccel * timeStep;
	
	if (dir.Dot(vector3d(rot[8], rot[9], rot[10])) > -0.999999)
		{ AIFaceDirection(dir); return false; }
	
	vector3d uphead = (updir * rot).Normalized();		// create desired object-space updir
	vector3d dav(0.0, 0.0, 0.0);			// desired angular velocity
	double ang = 0.0;
	if (uphead.y < 0.999999)
	{
		ang = acos(Clamp(uphead.y, -1.0, 1.0));		// scalar angle from head to curhead
		double iangvel = sqrt(2.0 * maxAccel * ang);	// ideal angvel at current time

		double frameEndAV = iangvel - frameAccel;
		if (frameEndAV <= 0.0) iangvel = ang / timeStep;	// last frame discrete correction
		else iangvel = (iangvel + frameEndAV) * 0.5;		// discrete overshoot correction
		dav.z = -iangvel;
	}
	vector3d cav = (GetAngVelocity() - GetFrame()->GetAngVelocity()) * rot;				// current obj-rel angvel
//	vector3d cav = GetAngVelocity() * rot;				// current obj-rel angvel
	vector3d diff = (dav - cav) / frameAccel;			// find diff between current & desired angvel

	SetAngThrusterState(diff);
	return ang;
//	if (diff.x*diff.x > 1.0 || diff.y*diff.y > 1.0 || diff.z*diff.z > 1.0) return false;
//	else return true;
}
Пример #4
0
vector3d TerrainColorFractal<TerrainColorVolcanic>::GetColor(const vector3d &p, double height, const vector3d &norm)
{
	double n = m_invMaxHeight*height;
	const double flatness = pow(p.Dot(norm), 6.0);
	const vector3d color_cliffs = m_rockColor[2];		
	double equatorial_desert = (-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) *
			1.0*(1.0-p.y*p.y);

	vector3d col;

	if (n > 0.4){
	col = interpolate_color(equatorial_desert, vector3d(.3,.2,0), vector3d(.3, .1, .0));
	col = interpolate_color(n, col, vector3d(.1, .0, .0));
	col = interpolate_color(flatness, color_cliffs, col);
	} else if (n > 0.2){
	col = interpolate_color(equatorial_desert, vector3d(1.2,1,0), vector3d(.9, .3, .0));
	col = interpolate_color(n, col, vector3d(-1.1, -1, .0));
	col = interpolate_color(flatness, color_cliffs, col);
	} else if (n > 0.1){
	col = interpolate_color(equatorial_desert, vector3d(.2,.1,0), vector3d(.1, .05, .0));
	col = interpolate_color(n, col, vector3d(2.5, 2, .0));
	col = interpolate_color(flatness, color_cliffs, col);
	} else {
	col = interpolate_color(equatorial_desert, vector3d(.75,.6,0), vector3d(.75, .2, .0));
	col = interpolate_color(n, col, vector3d(-2, -2.2, .0));
	col = interpolate_color(flatness, color_cliffs, col);
	}
	return col;
}
Пример #5
0
void CollisionSpace::CollideRaySphere(const vector3d &start, const vector3d &dir, isect_t *isect)
{
	if (sphere.radius > 0.0) {
		/* Collide with lovely sphere! */
		const vector3d v = start - sphere.pos;
		const double b = -v.Dot(dir);
		double det = (b * b) - v.LengthSqr() + (sphere.radius*sphere.radius);
		if (det > 0) {
			det = sqrt(det);
			const double i1 = b - det;
			const double i2 = b + det;
			if (i2 > 0) {
				/*if (i1 < 0) {
					if (i2 < *dist) {
						*dist = i2;
						//retval = INPRIM;
						retval = true;
					}
				}*/
				if (i1 > 0) {
					if (i1 < isect->dist) {
						isect->dist = float(i1);
						isect->triIdx = 0;
					}
				}
			}
		}
	}
}
Пример #6
0
// check whether ship is at risk of colliding with frame body on current path
// return values:
//0 - no collision
//1 - below feature height
//2 - unsafe escape from effect radius
//3 - unsafe entry to effect radius
//4 - probable path intercept
static int CheckCollision(Ship *ship, const vector3d &pathdir, double pathdist, const vector3d &tpos, double endvel, double r)
{
	// ship is in obstructor's frame anyway, so is tpos
	if (pathdist < 100.0) return 0;
	Body *body = ship->GetFrame()->GetBodyFor();
	if (!body) return 0;
	vector3d spos = ship->GetPosition();
	double tlen = tpos.Length(), slen = spos.Length();
	double fr = MaxFeatureRad(body);

	// if target inside, check if direct entry is safe (30 degree)
	if (tlen < r) {
		double af = (tlen > fr) ? 0.5 * (1 - (tlen-fr) / (r-fr)) : 0.5;
		if (pathdir.Dot(tpos) > -af*tlen)
			if (slen < fr) return 1; else return 3;
		else return 0;
	}

	// if ship inside, check for max feature height and direct escape (30 degree)
	if (slen < r) {
		if (slen < fr) return 1;
		double af = (slen > fr) ? 0.5 * (1 - (slen-fr) / (r-fr)) : 0.5;
		if (pathdir.Dot(spos) < af*slen) return 2; else return 0;
	}

	// now for the intercept calc
	// find closest point to obstructor
	double tanlen = -spos.Dot(pathdir);
	if (tanlen < 0 || tanlen > pathdist) return 0;		// closest point outside path

	vector3d perpdir = (tanlen*pathdir + spos).Normalized();
	double perpspeed = ship->GetVelocity().Dot(perpdir);
	double parspeed = ship->GetVelocity().Dot(pathdir);
	if (parspeed < 0) parspeed = 0;			// shouldn't break any important case
	if (perpspeed > 0) perpspeed = 0;		// prevent attempts to speculatively fly through planets

	// find time that ship will pass through that point
	// get velocity as if accelerating from start or end, pick smallest
	double ivelsqr = endvel*endvel + 2*ship->GetAccelFwd()*(pathdist-tanlen);		// could put endvel in here
	double fvelsqr = parspeed*parspeed + 2*ship->GetAccelFwd()*tanlen;
	double tanspeed = sqrt(ivelsqr < fvelsqr ? ivelsqr : fvelsqr);
	double time = tanlen / (0.5 * (parspeed + tanspeed));		// actually correct?

	double dist = spos.Dot(perpdir) + perpspeed*time;		// spos.perpdir should be positive
	if (dist < r) return 4;
	return 0;
}
Пример #7
0
static int GetFlipMode(Ship *ship, const vector3d &relpos, const vector3d &relvel)
{
	double dist = relpos.Length();
	double vel = relvel.Dot(relpos) / dist;
	if (vel > 0.0 && vel*vel > 1.7 * ship->GetAccelRev() * dist) return 2;
	if (dist > 100000000.0) return 1;	// arbitrary
	return 0;
}
Пример #8
0
// check for inability to reach target waypoint without overshooting
static bool CheckOvershoot(Ship *ship, const vector3d &reldir, double targdist, const vector3d &relvel, double endvel)
{
	if (targdist < 100.0) return false;		// spazzes out occasionally otherwise
	// only slightly fake minimum time to target
	// based on s = (sv+ev)*t/2 + a*t*t/4
	double fwdacc = ship->GetAccelFwd();
	double u = 0.5 * (relvel.Dot(reldir) + endvel);	if (u<0) u = 0;
	double t = (-u + sqrt(u*u + fwdacc*targdist)) / (fwdacc * 0.5);
	if (t < Pi::game->GetTimeStep()) t = Pi::game->GetTimeStep();
//	double t2 = ship->AITravelTime(reldir, targdist, relvel, endvel, true);

	// check for uncorrectable side velocity
	vector3d perpvel = relvel - reldir * relvel.Dot(reldir);
	if (perpvel.Length() > 0.5*ship->GetAccelMin()*t)
		return true;
	return false;
}
Пример #9
0
vector3d TerrainColorFractal<TerrainColorIce>::GetColor(const vector3d &p, double height, const vector3d &norm)
{
	double n = m_invMaxHeight*height;

	if (n <= 0.0) return vector3d(0.96,0.96,0.96);

	const double flatness = pow(p.Dot(norm), 24.0);
	double equatorial_desert = (2.0-m_icyness)*(-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) *
			1.0*(2.0-m_icyness)*(1.0-p.y*p.y);
	double equatorial_region_1 = billow_octavenoise(GetFracDef(0), 0.5, p) * p.y * p.y;
	double equatorial_region_2 = ridged_octavenoise(GetFracDef(5), 0.5, p) * p.x * p.x;
	// cliff colours
	vector3d color_cliffs;
	// adds some variation
	color_cliffs = interpolate_color(equatorial_region_1, m_rockColor[3],  m_rockColor[0] );
	color_cliffs = interpolate_color(equatorial_region_2, color_cliffs,  m_rockColor[2] );
	// main colours
	vector3d col;
	// start by interpolating between noise values for variation
	col = interpolate_color(equatorial_region_1, m_darkrockColor[0], vector3d(1, 1, 1) );
	col = interpolate_color(equatorial_region_2, m_darkrockColor[1], col );
	col = interpolate_color(equatorial_desert, col, vector3d(.96, .95, .94));
	// scale by different colours depending on height for more variation
	if (n > .666) {
		n -= 0.666; n*= 3.0;
		col = interpolate_color(n, vector3d(.96, .95, .94), col);
		col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else if (n > 0.333) {
		n -= 0.333; n*= 3.0;
		col = interpolate_color(n, col, vector3d(.96, .95, .94));
		col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else {
		n *= 3.0;
		col = interpolate_color(n, vector3d(.96, .95, .94), col);
		col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
}
Пример #10
0
// same inputs as matchposvel, returns approximate travel time instead
// underestimates if targspeed isn't reachable
double Ship::AITravelTime(const vector3d &reldir, double targdist, const vector3d &relvel, double targspeed, bool flip)
{
	double speed = relvel.Dot(reldir);		// speed >0 is towards
	double dist = targdist;
	double faccel = GetAccelFwd();
	double raccel = flip ? faccel : GetAccelRev();
	double time1, time2, time3;

	// time to reduce speed to zero:
	time1 = -speed / faccel;
	dist += 0.5 * time1 * -speed;

	// time to reduce speed to zero after target reached:
	time3 = -targspeed / raccel;
	dist += 0.5 * time3 * -targspeed;
	
	// now time to cover distance between zero-vel points
	// midpoint = intercept of two gradients
	double m = dist*raccel / (faccel+raccel);
	time2 = sqrt(2*m/faccel) + sqrt(2*(dist-m)/raccel);

	return time1+time2+time3;
}
Пример #11
0
vector3d TerrainColorFractal<TerrainColorDesert>::GetColor(const vector3d &p, double height, const vector3d &norm)
{
	double n = m_invMaxHeight*height/2;
	const double flatness = pow(p.Dot(norm), 6.0);
	const vector3d color_cliffs = m_rockColor[1];
	// Ice has been left as is so the occasional desert world will have polar ice-caps like mars
	if (fabs(m_icyness*p.y) + m_icyness*n > 1) {
		return interpolate_color(flatness, color_cliffs, vector3d(1,1,1));
	}
	double equatorial_desert = (2.0-m_icyness)*(-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) *
			1.0*(2.0-m_icyness)*(1.0-p.y*p.y);
	vector3d col;
	if (n > .4) {
		n = n*n;
		col = interpolate_color(equatorial_desert, vector3d(.8,.75,.5), vector3d(.52, .5, .3));
		col = interpolate_color(n, col, vector3d(.1, .0, .0));
		col = interpolate_color(flatness, color_cliffs, col);
		return col;
	} else if (n > .3) {
		n = n*n;
		col = interpolate_color(equatorial_desert, vector3d(.81, .68, .3), vector3d(.85, .7, 0));
		col = interpolate_color(n, col, vector3d(-1.2,-.84,.35));
		col = interpolate_color(flatness, color_cliffs, col);
		return col;
	} else if (n > .2) {
		col = interpolate_color(equatorial_desert, vector3d(-0.4, -0.47, -0.6), vector3d(-.6, -.7, -2));
		col = interpolate_color(n, col, vector3d(4, 3.95, 3.94));
		col = interpolate_color(flatness, color_cliffs, col);
		return col;
	} else {
		col = interpolate_color(equatorial_desert, vector3d(.78, .73, .68), vector3d(.8, .77, .5));
		col = interpolate_color(n, col, vector3d(-2.0, -2.3, -2.4));
		col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}	
}
Пример #12
0
// reldir*targdist and relvel are pos and vel of ship relative to target in ship's frame
// endspeed is in direction of motion, must be positive
// maxdecel is maximum deceleration thrust
bool Ship::AIMatchPosVel2(const vector3d &reldir, double targdist, const vector3d &relvel, double endspeed, double maxdecel)
{
	matrix4x4d rot; GetRotMatrix(rot);
	double parspeed = relvel.Dot(reldir);
	double ivel = calc_ivel(targdist, endspeed, maxdecel);
	double diffspeed = ivel - parspeed;
	vector3d diffvel = diffspeed * reldir * rot;
	bool rval = false;

	// crunch diffvel by relative thruster power to get acceleration in right direction
	if (diffspeed > 0.0) {
		vector3d maxFA = GetMaxThrust(diffvel) * Pi::game->GetTimeStep() / GetMass();
		if (abs(diffvel.x) > maxFA.x) diffvel *= maxFA.x / abs(diffvel.x);
		if (abs(diffvel.y) > maxFA.y) diffvel *= maxFA.y / abs(diffvel.y);
//		if (abs(diffvel.z) > maxFA.z) diffvel *= maxFA.z / abs(diffvel.z);
		if (maxFA.z < diffspeed) rval = true;
	}

	// add perpendicular velocity
	vector3d perpvel = relvel - parspeed*reldir;
	diffvel -= perpvel * rot;
	AIChangeVelBy(diffvel);
	return rval;			// true if acceleration was capped
}
Пример #13
0
float ShipCockpit::CalculateSignedForwardVelocity(vector3d normalized_forward, vector3d velocity) {
	float velz_cos = velocity.Dot(normalized_forward);
	return (velz_cos * normalized_forward).Length() * (velz_cos < 0.0 ? -1.0 : 1.0);
}
Пример #14
0
void AIParagonCmdSteerAround::CalculateEntryPoint()
{
	// Entry point
	if (m_data.ship_to_sbody_distance > m_data.sbody_transit_radius + 5000.0
		&& m_data.ship_to_sbody_distance <= m_data.sbody_transit_radius + 10000.0)
	{
		// - Ship is in transit range or nearby
		// --	Directly above or below to transit range is the entry point (Default)
		m_entryPoint = -m_data.ship_to_sbody_dir * m_data.sbody_transit_radius;
		m_stage = ESS_ENTER;
	} else if (m_data.ship_to_sbody_distance > m_data.sbody_transit_radius + 10000.0) {
		// - Ship is far from transit range
		vector3d intersection_point;
		bool intersection;
		// --	Calculate entry point
		if (m_data.target_to_sbody_distance > m_data.sbody_transit_radius) {
			// -- Target out of planet (WIP)
			// Ship takes a wide angle turn around the planet
			const double angle = DEG2RAD(45.0);
			const double ship_to_entry_distance = sqrt(2.0 * pow(m_data.ship_to_sbody_distance, 2));
			vector3d ship_up = m_ship->GetOrientRelTo(m_data.sframe).VectorY();
			
			// Get direction from ship to nearest entry point on planet hemisphere circular edge

			const vector3d ship_to_entry_dir =
				m_data.ship_to_sbody_dir * matrix4x4d::RotateMatrix(angle, ship_up.x, ship_up.y, ship_up.z);
			m_entryPoint = m_data.ship_pos + (ship_to_entry_dir * ship_to_entry_distance);

			// Planet could intersect path, in which case intersection point is the entry point
			if (LineSphereIntersection(m_data.sbody_pos, m_data.sbody_transit_radius,
				m_data.ship_pos, m_entryPoint, intersection_point)) {
				m_entryPoint = intersection_point;
			}
			m_stage = ESS_ENTER;
		} else {
			// -- Target in planet
			// is target in front or back hemisphere relative to ship?
			if (m_data.target_to_sbody_distance <= DESTINATION_RADIUS ||				
				-m_data.ship_to_sbody_dir.Dot(-m_data.target_to_sbody_dir) >= 0.0) {
				// Front hemisphere
				// Calculate location at which ship will enter transit-around heading towards target
				intersection = LineSphereIntersection(m_data.sbody_pos, m_data.sbody_transit_radius, 
					m_data.ship_pos, m_data.target_to_transit, intersection_point);
				assert(intersection);	// There should always be an intersection otherwise this code path would not run
										// If this exception is hit, it means there is a problem with the code that determines obstacles
				m_entryPoint = intersection_point;
				m_stage = ESS_ENTER;
			} else {
				// Back hemisphere
				// Enter point is the point that is exactly at 90 degrees planet-transit-radius from ship
				// If ship intersects radius before it reaches entry point then intersection point is the entry point
				const double angle = atan2(m_data.ship_to_sbody_distance, m_data.sbody_transit_radius);
				const double ship_to_entry_distance = sqrt(pow(m_data.ship_to_sbody_distance, 2) +
					pow(m_data.sbody_transit_radius, 2));
				const vector3d ship_up = m_ship->GetOrientRelTo(m_data.sframe).VectorY();

				// Get direction from ship to nearest entry point on planet hemisphere-edge
				// Note that entry point can be set anywhere around the planet's diameter from the ship's perspective
				vector3d sbody_to_target = -m_data.target_to_sbody_dir;
				sbody_to_target = sbody_to_target / ship_up.Dot(sbody_to_target);
				vector3d ship_to_entry_dir = (sbody_to_target - ship_up).Normalized();
				m_entryPoint = m_data.ship_pos + (ship_to_entry_dir * ship_to_entry_distance);

				// Planet could intersect path, in which case intersection point is the entry point
				if (LineSphereIntersection(m_data.sbody_pos, m_data.sbody_transit_radius,
					m_data.ship_pos, m_entryPoint, intersection_point)) {
					m_entryPoint = intersection_point;
				}
				m_stage = ESS_ENTER;
			}
		}
	} else {
		// --	Ship is already at entry point
		m_entryPoint = m_data.ship_pos;
		m_stage = ESS_AROUND;
	}
}
Пример #15
0
vector3d TerrainColorFractal<TerrainColorTFGood>::GetColor(const vector3d &p, double height, const vector3d &norm) const
{
    double n = m_invMaxHeight*height;
    const double flatness = pow(p.Dot(norm), 8.0);
    vector3d color_cliffs = m_rockColor[5];
    // ice on mountains and poles
    if (fabs(m_icyness*p.y) + m_icyness*n > 1) {
        return interpolate_color(flatness, color_cliffs, vector3d(1,1,1));
    }

    double equatorial_desert = (2.0-m_icyness)*(-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) *
                               1.0*(2.0-m_icyness)*(1.0-p.y*p.y);
    // This is for fake ocean depth by the coast.
    double continents = octavenoise(GetFracDef(0), 0.7*
                                    ridged_octavenoise(GetFracDef(8), 0.58, p), p) - m_sealevel*0.6;

    vector3d col;
    //we don't want water on the poles if there are ice-caps
    if (fabs(m_icyness*p.y) > 0.75) {
        col = interpolate_color(equatorial_desert, vector3d(0.42, 0.46, 0), vector3d(0.5, 0.3, 0));
        col = interpolate_color(flatness, col, vector3d(1,1,1));
        return col;
    }
    // water
    if (n <= 0) {
        // Oooh, pretty coastal regions with shading based on underwater depth.
        n += continents - (GetFracDef(0).amplitude*m_sealevel*0.49);
        n *= 10.0;
        n = (n>0.3 ? 0.3-(n*n*n-0.027) : n);
        col = interpolate_color(equatorial_desert, vector3d(0,0,0.15), vector3d(0,0,0.25));
        col = interpolate_color(n, col, vector3d(0,0.8,0.6));
        return col;
    }

    // More sensitive height detection for application of colours

    if (n > 0.5) {
        col = interpolate_color(equatorial_desert, m_rockColor[2], m_rockColor[4]);
        col = interpolate_color(n, col, m_darkrockColor[6]);
        col = interpolate_color(flatness, color_cliffs, col);
        return col;
    }
    else if (n > 0.25) {
        color_cliffs = m_darkrockColor[1];
        col = interpolate_color(equatorial_desert, m_darkrockColor[5], m_darkrockColor[7]);
        col = interpolate_color(n, col, m_rockColor[1]);
        col = interpolate_color(flatness, color_cliffs, col);
        return col;
    }
    else if (n > 0.05) {
        col = interpolate_color(equatorial_desert, m_darkrockColor[5], m_darkrockColor[7]);
        color_cliffs = col;
        col = interpolate_color(equatorial_desert, vector3d(.45,.43, .2), vector3d(.4, .43, .2));
        col = interpolate_color(n, col, vector3d(-1.66,-2.3, -1.75));
        col = interpolate_color(flatness, color_cliffs, col);
        return col;
    }
    else if (n > 0.01) {
        color_cliffs = vector3d(0.2,0.28,0.2);
        col = interpolate_color(equatorial_desert, vector3d(.15,.5, -.1), vector3d(.2, .6, -.1));
        col = interpolate_color(n, col, vector3d(5,-5, 5));
        col = interpolate_color(flatness, color_cliffs, col);
        return col;
    }
    else if (n > 0.005) {
        color_cliffs = vector3d(0.25,0.28,0.2);
        col = interpolate_color(equatorial_desert, vector3d(.45,.6,0), vector3d(.5, .6, .0));
        col = interpolate_color(n, col, vector3d(-10,-10,0));
        col = interpolate_color(flatness, color_cliffs, col);
        return col;
    }
    else {
        color_cliffs = vector3d(0.3,0.1,0.0);
        col = interpolate_color(equatorial_desert, vector3d(.35,.3,0), vector3d(.4, .3, .0));
        col = interpolate_color(n, col, vector3d(0,20,0));
        col = interpolate_color(flatness, color_cliffs, col);
        return col;
    }
}
vector3d TerrainColorFractal<TerrainColorEarthLikeHeightmapped>::GetColor(const vector3d &p, double height, const vector3d &norm) const
{
	double n = m_invMaxHeight*height;
	double flatness = pow(p.Dot(norm), 8.0);

	double equatorial_desert = (2.0-m_icyness)*(-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) *
			1.0*(2.0-m_icyness)*(1.0-p.y*p.y);
	vector3d color_cliffs = m_darkrockColor[5];
	vector3d col, tex1, tex2;

	if (n > 0) {
		// ice on mountains
		if (flatness > 0.6/Clamp(n*m_icyness+(m_icyness*0.5)+(fabs(p.y*p.y*p.y*0.38)), 0.1, 1.0)) {
			if (textures) {
				col = interpolate_color(terrain_colournoise_rock, color_cliffs, m_rockColor[5]);
				col = interpolate_color(flatness, col, vector3d(1,1,1));
			} else col = interpolate_color(flatness, color_cliffs, vector3d(1,1,1));
			return col;
		}
		//polar ice-caps
		if ((m_icyness*0.5)+(fabs(p.y*p.y*p.y*0.38)) > 0.6) {
			//if (flatness > 0.5/Clamp(fabs(p.y*m_icyness), 0.1, 1.0)) {
			if (textures) {
				col = interpolate_color(terrain_colournoise_rock, color_cliffs, m_rockColor[5]);
				col = interpolate_color(flatness, col, vector3d(1,1,1));
			} else col = interpolate_color(flatness, color_cliffs, vector3d(1,1,1));
			return col;
		}
	}

	// water
	if (n <= 0) {
		// waves
		if (textures) {
			n += terrain_colournoise_water;
			n *= 0.1;
		}
		col = interpolate_color(equatorial_desert, vector3d(0,0,0.15), vector3d(0,0,0.25));
		col = interpolate_color(n, col, vector3d(0,0.8,0.6));
		return col;
	}
	flatness = pow(p.Dot(norm), 16.0);
	// More sensitive height detection for application of colours
	if (n > 0.5) {
		n -= 0.5; n *= 2.0;
		color_cliffs = interpolate_color(n, m_darkrockColor[2], m_rockColor[4]);
		col = interpolate_color(equatorial_desert, m_rockColor[2], m_rockColor[4]);
		col = interpolate_color(n, col, m_darkrockColor[6]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_sand, col, m_darkdirtColor[3]);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else if (n > 0.25) {
		n -= 0.25; n *= 4.0;
		color_cliffs = interpolate_color(n, m_rockColor[3], m_darkplantColor[4]);
		col = interpolate_color(equatorial_desert, m_darkrockColor[3], m_darksandColor[1]);
		col = interpolate_color(n, col, m_rockColor[2]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_sand, col, m_darkdirtColor[3]);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else if (n > 0.05) {
		n -= 0.05; n *= 5.0;
		color_cliffs = interpolate_color(equatorial_desert, m_darkrockColor[5], m_darksandColor[7]);
		col = interpolate_color(equatorial_desert, m_darkplantColor[2], m_sandColor[2]);
		col = interpolate_color(n, col, m_darkrockColor[3]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_forest, col, color_cliffs);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else if (n > 0.01) {
		n -= 0.01; n *= 25.0;
		color_cliffs = m_darkdirtColor[7];
		col = interpolate_color(equatorial_desert, m_plantColor[1], m_plantColor[0]);
		col = interpolate_color(n, col, m_darkplantColor[2]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_grass, color_cliffs, col);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else if (n > 0.005) {
		n -= 0.005; n *= 200.0;
		color_cliffs = m_dirtColor[2];
		col = interpolate_color(equatorial_desert, m_darkplantColor[0], m_sandColor[1]);
		col = interpolate_color(n, col, m_plantColor[0]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_grass, color_cliffs, col);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else {
		n *= 200.0;
		color_cliffs = m_darksandColor[0];
		col = interpolate_color(equatorial_desert, m_sandColor[0], m_sandColor[1]);
		col = interpolate_color(n, col, m_darkplantColor[0]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_sand, col, color_cliffs);
			return col = interpolate_color(flatness, tex1, tex2);
		} else {
			return col = interpolate_color(flatness, color_cliffs, col);
		}
	}
}
Пример #17
0
// Calculates the ambiently and directly lit portions of the lighting model taking into account the atmosphere and sun positions at a given location
// 1. Calculates the amount of direct illumination available taking into account
//    * multiple suns
//    * sun positions relative to up direction i.e. light is dimmed as suns set
//    * Thickness of the atmosphere overhead i.e. as atmospheres get thicker light starts dimming earlier as sun sets, without atmosphere the light switches off at point of sunset
// 2. Calculates the split between ambient and directly lit portions taking into account
//    * Atmosphere density (optical thickness) of the sky dome overhead
//        as optical thickness increases the fraction of ambient light increases
//        this takes altitude into account automatically
//    * As suns set the split is biased towards ambient
void SpaceStation::CalcLighting(Planet *planet, double &ambient, double &intensity, const std::vector<Camera::LightSource> &lightSources)
{
	// position relative to the rotating frame of the planet
	vector3d upDir = GetPosition();
	const double dist = upDir.Length();
	upDir = upDir.Normalized();
	double pressure, density;
	planet->GetAtmosphericState(dist, &pressure, &density);
	double surfaceDensity;
	Color cl;
	planet->GetSystemBody()->GetAtmosphereFlavor(&cl, &surfaceDensity);

	// approximate optical thickness fraction as fraction of density remaining relative to earths
	double opticalThicknessFraction = density/EARTH_ATMOSPHERE_SURFACE_DENSITY;
	// tweak optical thickness curve - lower exponent ==> higher altitude before ambient level drops
	opticalThicknessFraction = pow(std::max(0.00001,opticalThicknessFraction),0.15); //max needed to avoid 0^power

	//step through all the lights and calculate contributions taking into account sun position
	double light = 0.0;
	double light_clamped = 0.0;

	for(std::vector<Camera::LightSource>::const_iterator l = lightSources.begin();
		l != lightSources.end(); ++l) {

			double sunAngle;
			// calculate the extent the sun is towards zenith
			if (l->GetBody()){
				// relative to the rotating frame of the planet
				const vector3d lightDir = (l->GetBody()->GetInterpPositionRelTo(planet->GetFrame()).Normalized());
				sunAngle = lightDir.Dot(upDir);
			} else {
				// light is the default light for systems without lights
				sunAngle = 1.0;
			}

			//0 to 1 as sunangle goes from 0.0 to 1.0
			double sunAngle2 = (Clamp(sunAngle, 0.0,1.0))/1.0;

			//0 to 1 as sunAngle goes from endAngle to startAngle

			// angle at which light begins to fade on Earth
			const double startAngle = 0.3;
			// angle at which sun set completes, which should be after sun has dipped below the horizon on Earth
			const double endAngle = -0.18;

			const double start = std::min((startAngle*opticalThicknessFraction),1.0);
			const double end = std::max((endAngle*opticalThicknessFraction),-0.2);

			sunAngle = (Clamp(sunAngle, end, start)-end)/(start-end);

			light += sunAngle;
			light_clamped += sunAngle2;
	}


	// brightness depends on optical depth and intensity of light from all the stars
	intensity = (Clamp((light),0.0,1.0));


	// ambient light fraction
	// alter ratio between directly and ambiently lit portions towards ambiently lit as sun sets
	const double fraction = (0.1+0.8*(
						1.0-light_clamped*(Clamp((opticalThicknessFraction),0.0,1.0))
						)+0.1); //fraction goes from 0.6 to 1.0


	// fraction of light left over to be lit directly
	intensity = (1.0-fraction)*intensity;

	// scale ambient by amount of light
	ambient = fraction*(Clamp((light),0.0,1.0))*0.25;
}
Пример #18
0
// Calculates the ambiently and directly lit portions of the lighting model taking into account the atmosphere and sun positions at a given location
// 1. Calculates the amount of direct illumination available taking into account
//    * multiple suns
//    * sun positions relative to up direction i.e. light is dimmed as suns set
//    * Thickness of the atmosphere overhead i.e. as atmospheres get thicker light starts dimming earlier as sun sets, without atmosphere the light switches off at point of sunset
// 2. Calculates the split between ambient and directly lit portions taking into account
//    * Atmosphere density (optical thickness) of the sky dome overhead
//        as optical thickness increases the fraction of ambient light increases
//        this takes altitude into account automatically
//    * As suns set the split is biased towards ambient
void ModelBody::CalcLighting(double &ambient, double &direct, const Camera *camera)
{
	const double minAmbient = 0.05;
	ambient = minAmbient;
	direct = 1.0;
	Body *astro = GetFrame()->GetBody();
	if ( ! (astro && astro->IsType(Object::PLANET)) )
		return;

	Planet *planet = static_cast<Planet*>(astro);

	// position relative to the rotating frame of the planet
	vector3d upDir = GetInterpPositionRelTo(planet->GetFrame());
	const double planetRadius = planet->GetSystemBody()->GetRadius();
	const double dist = std::max(planetRadius, upDir.Length());
	upDir = upDir.Normalized();

	double pressure, density;
	planet->GetAtmosphericState(dist, &pressure, &density);
	double surfaceDensity;
	Color cl;
	planet->GetSystemBody()->GetAtmosphereFlavor(&cl, &surfaceDensity);

	// approximate optical thickness fraction as fraction of density remaining relative to earths
	double opticalThicknessFraction = density/EARTH_ATMOSPHERE_SURFACE_DENSITY;

	// tweak optical thickness curve - lower exponent ==> higher altitude before ambient level drops
	// Commenting this out, since it leads to a sharp transition at
	// atmosphereRadius, where density is suddenly 0
	//opticalThicknessFraction = pow(std::max(0.00001,opticalThicknessFraction),0.15); //max needed to avoid 0^power

	if (opticalThicknessFraction < 0.0001)
		return;

	//step through all the lights and calculate contributions taking into account sun position
	double light = 0.0;
	double light_clamped = 0.0;

	const std::vector<Camera::LightSource> &lightSources = camera->GetLightSources();
	for(std::vector<Camera::LightSource>::const_iterator l = lightSources.begin();
			l != lightSources.end(); ++l) {

		double sunAngle;
		// calculate the extent the sun is towards zenith
		if (l->GetBody()){
			// relative to the rotating frame of the planet
			const vector3d lightDir = (l->GetBody()->GetInterpPositionRelTo(planet->GetFrame()).Normalized());
			sunAngle = lightDir.Dot(upDir);
		} else {
			// light is the default light for systems without lights
			sunAngle = 1.0;
		}

		const double critAngle = -sqrt(dist*dist-planetRadius*planetRadius)/dist;

		//0 to 1 as sunangle goes from critAngle to 1.0
		double sunAngle2 = (Clamp(sunAngle, critAngle, 1.0)-critAngle)/(1.0-critAngle);

		// angle at which light begins to fade on Earth
		const double surfaceStartAngle = 0.3;
		// angle at which sun set completes, which should be after sun has dipped below the horizon on Earth
		const double surfaceEndAngle = -0.18;

		const double start = std::min((surfaceStartAngle*opticalThicknessFraction),1.0);
		const double end = std::max((surfaceEndAngle*opticalThicknessFraction),-0.2);

		sunAngle = (Clamp(sunAngle-critAngle, end, start)-end)/(start-end);

		light += sunAngle;
		light_clamped += sunAngle2;
	}

	light_clamped /= lightSources.size();
	light /= lightSources.size();

	// brightness depends on optical depth and intensity of light from all the stars
	direct = 1.0 -  Clamp((1.0 - light),0.0,1.0) * Clamp(opticalThicknessFraction,0.0,1.0);

	// ambient light fraction
	// alter ratio between directly and ambiently lit portions towards ambiently lit as sun sets
	const double fraction = ( 0.2 + 0.8 * (1.0-light_clamped) ) * Clamp(opticalThicknessFraction,0.0,1.0);

	// fraction of light left over to be lit directly
	direct = (1.0-fraction)*direct;

	// scale ambient by amount of light
	ambient = fraction*(Clamp((light),0.0,1.0))*0.25;

	ambient = std::max(minAmbient, ambient);
}
Пример #19
0
static void hitCallback(CollisionContact *c)
{
    //printf("OUCH! %x (depth %f)\n", SDL_GetTicks(), c->depth);

    Object *po1 = static_cast<Object*>(c->userData1);
    Object *po2 = static_cast<Object*>(c->userData2);

    const bool po1_isDynBody = po1->IsType(Object::DYNAMICBODY);
    const bool po2_isDynBody = po2->IsType(Object::DYNAMICBODY);
    // collision response
    assert(po1_isDynBody || po2_isDynBody);

    if (po1_isDynBody && po2_isDynBody) {
        DynamicBody *b1 = static_cast<DynamicBody*>(po1);
        DynamicBody *b2 = static_cast<DynamicBody*>(po2);
        const vector3d linVel1 = b1->GetVelocity();
        const vector3d linVel2 = b2->GetVelocity();
        const vector3d angVel1 = b1->GetAngVelocity();
        const vector3d angVel2 = b2->GetAngVelocity();

        const double coeff_rest = 0.5;
        // step back
//		mover->UndoTimestep();

        const double invMass1 = 1.0 / b1->GetMass();
        const double invMass2 = 1.0 / b2->GetMass();
        const vector3d hitPos1 = c->pos - b1->GetPosition();
        const vector3d hitPos2 = c->pos - b2->GetPosition();
        const vector3d hitVel1 = linVel1 + angVel1.Cross(hitPos1);
        const vector3d hitVel2 = linVel2 + angVel2.Cross(hitPos2);
        const double relVel = (hitVel1 - hitVel2).Dot(c->normal);
        // moving away so no collision
        if (relVel > 0) return;
        if (!OnCollision(po1, po2, c, -relVel)) return;
        const double invAngInert1 = 1.0 / b1->GetAngularInertia();
        const double invAngInert2 = 1.0 / b2->GetAngularInertia();
        const double numerator = -(1.0 + coeff_rest) * relVel;
        const double term1 = invMass1;
        const double term2 = invMass2;
        const double term3 = c->normal.Dot((hitPos1.Cross(c->normal)*invAngInert1).Cross(hitPos1));
        const double term4 = c->normal.Dot((hitPos2.Cross(c->normal)*invAngInert2).Cross(hitPos2));

        const double j = numerator / (term1 + term2 + term3 + term4);
        const vector3d force = j * c->normal;

        b1->SetVelocity(linVel1 + force*invMass1);
        b1->SetAngVelocity(angVel1 + hitPos1.Cross(force)*invAngInert1);
        b2->SetVelocity(linVel2 - force*invMass2);
        b2->SetAngVelocity(angVel2 - hitPos2.Cross(force)*invAngInert2);
    } else {
        // one body is static
        vector3d hitNormal;
        DynamicBody *mover;

        if (po1_isDynBody) {
            mover = static_cast<DynamicBody*>(po1);
            hitNormal = c->normal;
        } else {
            mover = static_cast<DynamicBody*>(po2);
            hitNormal = -c->normal;
        }

        const double coeff_rest = 0.5;
        const vector3d linVel1 = mover->GetVelocity();
        const vector3d angVel1 = mover->GetAngVelocity();

        // step back
//		mover->UndoTimestep();

        const double invMass1 = 1.0 / mover->GetMass();
        const vector3d hitPos1 = c->pos - mover->GetPosition();
        const vector3d hitVel1 = linVel1 + angVel1.Cross(hitPos1);
        const double relVel = hitVel1.Dot(c->normal);
        // moving away so no collision
        if (relVel > 0 && !c->geomFlag) return;
        if (!OnCollision(po1, po2, c, -relVel)) return;
        const double invAngInert = 1.0 / mover->GetAngularInertia();
        const double numerator = -(1.0 + coeff_rest) * relVel;
        const double term1 = invMass1;
        const double term3 = c->normal.Dot((hitPos1.Cross(c->normal)*invAngInert).Cross(hitPos1));

        const double j = numerator / (term1 + term3);
        const vector3d force = j * c->normal;

        mover->SetVelocity(linVel1 + force*invMass1);
        mover->SetAngVelocity(angVel1 + hitPos1.Cross(force)*invAngInert);
    }
}
Пример #20
0
vector3d TerrainColorFractal<TerrainColorTFPoor>::GetColor(const vector3d &p, double height, const vector3d &norm) const
{
	double n = m_invMaxHeight*height;
	double flatness = pow(p.Dot(norm), 8.0);

	double continents = 0;
	double equatorial_desert = (2.0-m_icyness)*(-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) *
			1.0*(2.0-m_icyness)*(1.0-p.y*p.y);
	vector3d color_cliffs = m_darkrockColor[5];
	vector3d col, tex1, tex2;
	// ice on mountains and poles
	if (fabs(m_icyness*p.y) + m_icyness*n > 1) {
		if (textures) {
			col = interpolate_color(terrain_colournoise_rock2, color_cliffs, vector3d(.9,.9,.9));
			col = interpolate_color(flatness, col, vector3d(1,1,1));
		} else col = interpolate_color(flatness, color_cliffs, vector3d(1,1,1));
		return col;
	}
	//we don't want water on the poles if there are ice-caps
	if (fabs(m_icyness*p.y) > 0.67) {
		col = interpolate_color(equatorial_desert, m_sandColor[2], m_darksandColor[5]);
		col = interpolate_color(flatness, col, vector3d(1,1,1));
		return col;
	}
	// This is for fake ocean depth by the coast.
	continents = ridged_octavenoise(GetFracDef(3-m_fracnum), 0.55, p) * (1.0-m_sealevel) - ((m_sealevel*0.1)-0.1);

	// water
	if (n <= 0) {
		// Oooh, pretty coastal regions with shading based on underwater depth.
		n += continents;// - (GetFracDef(3).amplitude*m_sealevel*0.49);
		n *= n*10.0;
		//n = (n>0.3 ? 0.3-(n*n*n-0.027) : n);
		col = interpolate_color(n, vector3d(0,0.0,0.1), vector3d(0,0.5,0.5));
		return col;
	}
	// More sensitive height detection for application of colours
	if (n > 0.5) {
		n -= 0.5; n *= 2.0;
		//color_cliffs = m_rockColor[1];
		col = interpolate_color(equatorial_desert, m_rockColor[2], m_rockColor[6]);
		col = interpolate_color(n, col, m_darkrockColor[6]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_rock2, col, color_cliffs);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else if (n > 0.25) {
		n -= 0.25; n *= 4.0;
		color_cliffs = m_rockColor[3];
		col = interpolate_color(equatorial_desert, m_darkrockColor[4], m_darksandColor[6]);
		col = interpolate_color(n, col, m_rockColor[2]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_mud, col, color_cliffs);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else if (n > 0.05) {
		n -= 0.05; n *= 5.0;
		col = interpolate_color(equatorial_desert, m_darkrockColor[5], m_darksandColor[7]);
		color_cliffs = col;
		col = interpolate_color(equatorial_desert, m_darksandColor[2], m_sandColor[2]);
		col = interpolate_color(n, col, m_darkrockColor[3]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_mud, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_grass, col, color_cliffs);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else if (n > 0.01) {
		n -= 0.01; n *= 25.0;
		color_cliffs = m_darkplantColor[0];
		col = interpolate_color(equatorial_desert, m_sandColor[1], m_sandColor[0]);
		col = interpolate_color(n, col, m_darksandColor[2]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_grass, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_grass2, col, color_cliffs);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else if (n > 0.005) {
		n -= 0.005; n *= 200.0;
		color_cliffs = m_plantColor[0];
		col = interpolate_color(equatorial_desert, m_darkplantColor[0], m_sandColor[1]);
		col = interpolate_color(n, col, m_plantColor[0]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_sand2, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_grass, col, color_cliffs);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else {
		n *= 200.0;
		color_cliffs = m_darksandColor[0];
		col = interpolate_color(equatorial_desert, m_sandColor[0], m_sandColor[1]);
		col = interpolate_color(n, col, m_darkplantColor[0]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_sand, col, color_cliffs);
			//tex2 = interpolate_color(terrain_colournoise_sand2, col, color_cliffs);
			col = interpolate_color(flatness, tex1, col);
		} else col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
}
Пример #21
0
vector3d TerrainColorFractal<TerrainColorEarthLike>::GetColor(const vector3d &p, double height, const vector3d &norm)
{
	double n = m_invMaxHeight*height;
	double flatness = pow(p.Dot(norm), 8.0);
	//textures:
	double tex_rock(0), tex_sand(0), tex_grass(0), tex_forest(0);

	if (textures) {
		tex_rock   =   rock;
		tex_sand   =   sand;
		tex_grass  =  grass;
		tex_forest = forest;
	}
	//textures end
	double continents = 0;
	double equatorial_desert = (2.0-m_icyness)*(-1.0+2.0*octavenoise(12, 0.5, 2.0, (n*2.0)*p)) *
			1.0*(2.0-m_icyness)*(1.0-p.y*p.y);
	vector3d color_cliffs = m_darkrockColor[5];
	vector3d col, tex1, tex2;
	
	if (m_heightMap) {
		if (n > 0) {
			// ice on mountains
			if (flatness > 0.6/Clamp(n*m_icyness+(m_icyness*0.5)+(fabs(p.y*p.y*p.y*0.38)), 0.1, 1.0)) {
				if (textures) {
					col = interpolate_color(tex_rock, color_cliffs, m_rockColor[5]);
					col = interpolate_color(flatness, col, vector3d(1,1,1));
				} else col = interpolate_color(flatness, color_cliffs, vector3d(1,1,1));
				return col;
			}
			//polar ice-caps
			if ((m_icyness*0.5)+(fabs(p.y*p.y*p.y*0.38)) > 0.6) {
				//if (flatness > 0.5/Clamp(fabs(p.y*m_icyness), 0.1, 1.0)) {
				if (textures) {
					col = interpolate_color(tex_rock, color_cliffs, m_rockColor[5]);
					col = interpolate_color(flatness, col, vector3d(1,1,1));
				} else col = interpolate_color(flatness, color_cliffs, vector3d(1,1,1));
				return col;
			}
		}
	} else {
		// ice on mountains
		//printf("flatness : %d", flatness);
		if (flatness > 0.6/Clamp(n*m_icyness+(m_icyness*0.5)+(fabs(p.y*p.y*p.y*0.38)), 0.1, 1.0)) {
			if (textures) {
				col = interpolate_color(tex_rock, color_cliffs, m_rockColor[5]);
				col = interpolate_color(flatness, col, vector3d(1,1,1));
			} else col = interpolate_color(flatness, color_cliffs, vector3d(1,1,1));
			return col;
		}
		//polar ice-caps
		if ((m_icyness*0.5)+(fabs(p.y*p.y*p.y*0.38)) > 0.6) {
			//if (flatness > 0.5/Clamp(fabs(p.y*m_icyness), 0.1, 1.0)) {
			if (textures) {
				col = interpolate_color(tex_rock, color_cliffs, m_rockColor[5]);
				col = interpolate_color(flatness, col, vector3d(1,1,1));
			} else col = interpolate_color(flatness, color_cliffs, vector3d(1,1,1));
			return col;
		}
	}
	

	// This is for fake ocean depth by the coast.
		if (m_heightMap) {
			continents = 0;
		} else {
			continents = ridged_octavenoise(GetFracDef(3-m_fracnum), 0.55, p) * (1.0-m_sealevel) - ((m_sealevel*0.1)-0.1);
		}
	// water
	if (n <= 0) {
		if (m_heightMap) {	
			// waves
			if (textures) {
				n += water;
				n *= 0.1;
			}
		} else {
		// Oooh, pretty coastal regions with shading based on underwater depth.
			n += continents;// - (GetFracDef(3).amplitude*m_sealevel*0.49);
			n *= n*10.0;
			//n = (n>0.3 ? 0.3-(n*n*n-0.027) : n);
		}
		col = interpolate_color(equatorial_desert, vector3d(0,0,0.15), vector3d(0,0,0.25));
		col = interpolate_color(n, col, vector3d(0,0.8,0.6));
		return col;
	}
	flatness = pow(p.Dot(norm), 16.0);
	// More sensitive height detection for application of colours	
	if (n > 0.5) {
		n -= 0.5; n *= 2.0;
		color_cliffs = interpolate_color(n, m_darkrockColor[2], m_rockColor[4]);
		col = interpolate_color(equatorial_desert, m_rockColor[2], m_rockColor[4]);
		col = interpolate_color(n, col, m_darkrockColor[6]);
		if (textures) {
			tex1 = interpolate_color(tex_rock, col, color_cliffs);
			tex2 = interpolate_color(tex_sand, col, m_darkdirtColor[3]);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else if (n > 0.25) { 
		n -= 0.25; n *= 4.0;
		color_cliffs = interpolate_color(n, m_rockColor[3], m_darkplantColor[4]);
		col = interpolate_color(equatorial_desert, m_darkrockColor[3], m_darksandColor[1]);
		col = interpolate_color(n, col, m_rockColor[2]);
		if (textures) {
			tex1 = interpolate_color(tex_rock, col, color_cliffs);
			tex2 = interpolate_color(tex_sand, col, m_darkdirtColor[3]);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else if (n > 0.05) {  
		n -= 0.05; n *= 5.0;
		color_cliffs = interpolate_color(equatorial_desert, m_darkrockColor[5], m_darksandColor[7]);			
		col = interpolate_color(equatorial_desert, m_darkplantColor[2], m_sandColor[2]);
		col = interpolate_color(n, col, m_darkrockColor[3]);
		if (textures) {
			tex1 = interpolate_color(tex_rock, col, color_cliffs);
			tex2 = interpolate_color(tex_forest, col, color_cliffs);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else if (n > 0.01) {
		n -= 0.01; n *= 25.0;
		color_cliffs = m_darkdirtColor[7];
		col = interpolate_color(equatorial_desert, m_plantColor[1], m_plantColor[0]);
		col = interpolate_color(n, col, m_darkplantColor[2]);
		if (textures) {
			tex1 = interpolate_color(tex_rock, col, color_cliffs);
			tex2 = interpolate_color(tex_grass, color_cliffs, col);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else if (n > 0.005) {   
		n -= 0.005; n *= 200.0;
		color_cliffs = m_dirtColor[2];
		col = interpolate_color(equatorial_desert, m_darkplantColor[0], m_sandColor[1]);
		col = interpolate_color(n, col, m_plantColor[0]);
		if (textures) {
			tex1 = interpolate_color(tex_rock, col, color_cliffs);
			tex2 = interpolate_color(tex_grass, color_cliffs, col);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
		return col;
	}
	else { 
		n *= 200.0;
		color_cliffs = m_darksandColor[0];
		col = interpolate_color(equatorial_desert, m_sandColor[0], m_sandColor[1]);
		col = interpolate_color(n, col, m_darkplantColor[0]);
		if (textures) {
			tex1 = interpolate_color(tex_rock, col, color_cliffs);
			tex2 = interpolate_color(tex_sand, col, color_cliffs);
			return col = interpolate_color(flatness, tex1, tex2);
		} else { 
			return col = interpolate_color(flatness, color_cliffs, col);
		}
	}
}
Пример #22
0
vector3d TerrainColorFractal<TerrainColorRock>::GetColor(const vector3d &p, double height, const vector3d &norm)
{
	double n = m_invMaxHeight*height/2;
	if (n <= 0) return m_darkrockColor[0];
	const double flatness = pow(p.Dot(norm), 20.0);
	const vector3d color_cliffs = m_rockColor[0];
	double equatorial_desert = (2.0-m_icyness)*(-1.0+2.0*octavenoise(4, 0.05, 2.0, (n*2.0)*p)) *
		1.0*(2.0-m_icyness)*(1.0-p.y*p.y);
	//double equatorial_region = octavenoise(GetFracDef(0), 0.54, p) * p.y * p.x;
	//double equatorial_region_2 = ridged_octavenoise(GetFracDef(1), 0.58, p) * p.x * p.x;
	// Below is to do with variable colours for different heights, it gives a nice effect.
	// n is height.
	vector3d col, tex1, tex2;
	col = interpolate_color(equatorial_desert, m_rockColor[2], m_darkrockColor[4]);
	//col = interpolate_color(equatorial_region, col, m_darkrockColor[4]);
	//col = interpolate_color(equatorial_region_2, m_rockColor[1], col);
	if (n > 0.9) {
		n -= 0.9; n *= 10.0;
		col = interpolate_color(n, m_rockColor[5], col );
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_mud, col, color_cliffs);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
	return col;
	}
	else if (n > 0.8) {
		n -= 0.8; n *= 10.0;
		col = interpolate_color(n, col, m_rockColor[5]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_mud, col, color_cliffs);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
	return col;
	}
	else if (n > 0.7) {
		n -= 0.7; n *= 10.0;
		col = interpolate_color(n, m_rockColor[4], col);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_mud, col, color_cliffs);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
	return col;
	}
	else if (n > 0.6) {
		n -= 0.6; n *= 10.0;
		col = interpolate_color(n, m_rockColor[1], m_rockColor[4]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock2, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_mud, col, m_rockColor[3]);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
	return col;
	}
	else if (n > 0.5) {
		n -= 0.5; n *= 10.0;
		col = interpolate_color(n, col, m_rockColor[1]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock2, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_rock, col, color_cliffs);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
	return col;
	}
	else if (n > 0.4) {
		n -= 0.4; n *= 10.0;
		col = interpolate_color(n, m_darkrockColor[3], col);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_mud, col, m_rockColor[3]);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
	return col;
	}
	if (n > 0.3) {
		n -= 0.3; n *= 10.0;
		col = interpolate_color(n, col, m_darkrockColor[3]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock2, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_mud, col, m_darkrockColor[6]);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
	return col;
	}
	else if (n > 0.2) {
		n -= 0.2; n *= 10.0;
		col = interpolate_color(n, m_rockColor[1], col);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_rock2, col, color_cliffs);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
	return col;
	}
	else if (n > 0.1) {
		n -= 0.1; n *= 10.0;
		col = interpolate_color(n, col, m_rockColor[1]);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock2, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_mud, col, m_rockColor[3]);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
	return col;
	}
	else {
		n *= 10.0;
		col = interpolate_color(n, m_darkrockColor[0], col);
		if (textures) {
			tex1 = interpolate_color(terrain_colournoise_rock, col, color_cliffs);
			tex2 = interpolate_color(terrain_colournoise_mud, col, color_cliffs);
			col = interpolate_color(flatness, tex1, tex2);
		} else col = interpolate_color(flatness, color_cliffs, col);
	return col;
	}
}