diff options
| author | max-001 <maxsmits21@kpnmail.nl> | 2024-12-09 14:14:03 +0100 | 
|---|---|---|
| committer | max-001 <maxsmits21@kpnmail.nl> | 2024-12-09 14:14:03 +0100 | 
| commit | 857e408d6d3a8631b61ebd283b337819783f092c (patch) | |
| tree | eb201efe09f033187c2ce9c51f68f0239e548a5d /src | |
| parent | cdaf587006053874c2e286a7541e6a2b246ce2b3 (diff) | |
Implemented oval path
Diffstat (limited to 'src')
| -rw-r--r-- | src/crepe/api/AI.cpp | 46 | ||||
| -rw-r--r-- | src/crepe/api/AI.h | 14 | ||||
| -rw-r--r-- | src/example/AITest.cpp | 4 | 
3 files changed, 62 insertions, 2 deletions
diff --git a/src/crepe/api/AI.cpp b/src/crepe/api/AI.cpp index 49f6b92..00e5b37 100644 --- a/src/crepe/api/AI.cpp +++ b/src/crepe/api/AI.cpp @@ -27,4 +27,50 @@ void AI::make_circle_path(float radius, vec2 center, float start_angle, bool clo  	}  } +void AI::make_oval_path(float radius_x, float radius_y, vec2 center, float start_angle, +						bool clockwise, float rotation) { +	float max_radius = std::max(radius_x, radius_y); +	// The step size is determined by the radius (step size is in radians) +	float step = 400.0f / max_radius; +	// Force at least 16 steps (in case of a small radius) +	if (step > 2 * M_PI / 16) { +		step = 2 * M_PI / 16; +	} +	// The path node distance is determined by the step size and the radius +	path_node_distance = max_radius * step * 0.75f; + +	auto rotate_point = [rotation](vec2 point, vec2 center) { +		float s = sin(rotation); +		float c = cos(rotation); + +		// Translate point back to origin +		point.x -= center.x; +		point.y -= center.y; + +		// Rotate point +		float xnew = point.x * c - point.y * s; +		float ynew = point.x * s + point.y * c; + +		// Translate point back +		point.x = xnew + center.x; +		point.y = ynew + center.y; + +		return point; +	}; + +	if (clockwise) { +		for (float i = start_angle; i < 2 * M_PI + start_angle; i += step) { +			vec2 point = {static_cast<float>(center.x + radius_x * cos(i)), +						  static_cast<float>(center.y + radius_y * sin(i))}; +			path.push_back(rotate_point(point, center)); +		} +	} else { +		for (float i = start_angle; i > start_angle - 2 * M_PI; i -= step) { +			vec2 point = {static_cast<float>(center.x + radius_x * cos(i)), +						  static_cast<float>(center.y + radius_y * sin(i))}; +			path.push_back(rotate_point(point, center)); +		} +	} +} +  } // namespace crepe diff --git a/src/crepe/api/AI.h b/src/crepe/api/AI.h index 0dccd5f..c95924d 100644 --- a/src/crepe/api/AI.h +++ b/src/crepe/api/AI.h @@ -81,6 +81,20 @@ public:  	 */  	void make_circle_path(float radius, vec2 center = {0, 0}, float start_angle = 0,  						  bool clockwise = true); +	/** +	 * \brief Make an oval path (for the path following behavior) +	 * +	 * \note The path is not relative to the entity's position (it is an absolute path) +	 * +	 * \param radius_x The x radius of the oval (in game units) +	 * \param radius_y The y radius of the oval (in game units) +	 * \param center The center of the oval (in game units) +	 * \param start_angle The start angle of the oval (in radians) +	 * \param clockwise The direction of the oval +	 * \param rotation The rotation of the oval (in radians) +	 */ +	void make_oval_path(float radius_x, float radius_y, vec2 center = {0, 0}, +						float start_angle = 0, bool clockwise = true, float rotation = 0);  public:  	//! The maximum force that can be applied to the entity (higher values will make the entity adjust faster) diff --git a/src/example/AITest.cpp b/src/example/AITest.cpp index 28537ed..f4efc9f 100644 --- a/src/example/AITest.cpp +++ b/src/example/AITest.cpp @@ -59,8 +59,8 @@ public:  		// ai.arrive_on();  		// ai.flee_on();  		ai.path_follow_on(); -		ai.make_circle_path(1000, {0, -1000}, 1.5707, true); -		ai.make_circle_path(1000, {0, 1000}, 4.7124, false); +		ai.make_oval_path(500, 1000, {0, -1000}, 1.5708, true); +		ai.make_oval_path(1000, 500, {0, 500}, 4.7124, false);  		game_object1.add_component<Rigidbody>(Rigidbody::Data{  			.mass = 0.1f,  			.max_linear_velocity = {40, 40},  |