00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00034
00035 #pragma once
00036
00037 #include "../api_display.h"
00038 #include <vector>
00039 #include "contour.h"
00040 #include "outline_accuracy.h"
00041 #include "../Render/graphic_context.h"
00042 #include "../../Core/Resources/resource.h"
00043 #include "../../Core/Math/cl_math.h"
00044 #include "../../Core/Math/origin.h"
00045 #include "../../Core/Math/circle.h"
00046 #include "../../Core/IOData/virtual_directory.h"
00047
00048 class CL_CollisionOutline_Generic;
00049 class CL_ResourceManager;
00050 class CL_OutputSourceProvider;
00051 class CL_GraphicContext;
00052 class CL_Color;
00053
00058 struct CL_CollisionPoint
00059 {
00061 CL_Pointf point;
00062
00064 CL_Pointf normal;
00065
00067 bool is_entry;
00068
00070 int contour1_line_start, contour2_line_start, contour1_line_end, contour2_line_end;
00071 };
00072
00077 struct CL_CollidingContours
00078 {
00079 const CL_Contour *contour1;
00080 const CL_Contour *contour2;
00081 bool inside;
00082 std::vector<CL_CollisionPoint> points;
00083
00084 CL_Pointf penetration_normal;
00085 float penetration_depth;
00086 CL_Pointf contour1_deep_point;
00087 CL_Pointf contour2_deep_point;
00088
00094 CL_CollidingContours(const CL_Contour *c1, const CL_Contour *c2, bool in=false) :
00095 contour1(c1),
00096 contour2(c2),
00097 inside(in),
00098 penetration_normal(0.0, 0.0),
00099 penetration_depth(0.0),
00100 contour1_deep_point(0.0, 0.0),
00101 contour2_deep_point(0.0, 0.0)
00102 {
00103 points.clear();
00104 }
00105 };
00106
00111 class CL_API_DISPLAY CL_CollisionOutline
00112 {
00115 public:
00117 CL_CollisionOutline();
00118
00124 CL_CollisionOutline(const CL_PixelBuffer &pbuf, int alpha_limit=128, CL_OutlineAccuracy accuracy=accuracy_medium );
00125
00132 CL_CollisionOutline(const CL_StringRef &fullname, int alpha_limit=128, CL_OutlineAccuracy accuracy=accuracy_medium, bool get_insides=true);
00133
00141 CL_CollisionOutline(CL_IODevice &file, const CL_String &file_extension, int alpha_limit=128, CL_OutlineAccuracy accuracy=accuracy_medium, bool get_insides=true);
00142
00150 CL_CollisionOutline(const CL_StringRef &filename, const CL_VirtualDirectory &directory, int alpha_limit=128, CL_OutlineAccuracy accuracy=accuracy_medium, bool get_insides=true);
00151
00156 CL_CollisionOutline(const CL_StringRef &resource_id, CL_ResourceManager *manager );
00157
00163 CL_CollisionOutline(std::vector<CL_Contour> contours, int width, int height);
00164
00165 ~CL_CollisionOutline();
00166
00170 public:
00172 const CL_Contour &get_object_bounding_box() const;
00173
00175
00176 CL_Circlef get_minimum_enclosing_disc() const;
00177
00179 bool get_inside_test() const;
00180
00182 std::vector<CL_Contour> &get_contours();
00183 const std::vector<CL_Contour> &get_contours() const;
00184
00186 CL_Pointf get_translation() const;
00187
00189 CL_Pointf get_scale() const;
00190
00192 float get_angle() const;
00193
00195 unsigned int get_width() const;
00196
00198 unsigned int get_height() const;
00199
00201 void get_alignment( CL_Origin &origin, float &x, float &y ) const;
00202
00204 void get_rotation_hotspot( CL_Origin &origin, float &x, float &y) const;
00205
00207 const std::vector<CL_CollidingContours> &get_collision_info() const;
00208
00210 void get_collision_info_state(bool &points, bool &normals, bool &metadata, bool &pendepth) const;
00211
00213 CL_Resource resource;
00214
00218 public:
00222 void load(const CL_StringRef &fullname);
00223
00228 void load(const CL_StringRef &filename, const CL_VirtualDirectory &directory);
00229
00233 void load(CL_IODevice &file);
00234
00236 CL_CollisionOutline ©(const CL_CollisionOutline &other);
00237
00239 CL_CollisionOutline clone() const;
00240
00245 void optimize( unsigned char check_distance=3, float corner_angle = CL_PI / 5.0 );
00246
00255 void draw(
00256 float x,
00257 float y,
00258 const CL_Colorf &color,
00259 CL_GraphicContext &gc);
00260
00269 void draw_sub_circles(
00270 float x,
00271 float y,
00272 const CL_Colorf &color,
00273 CL_GraphicContext &gc);
00274
00283 void draw_smallest_enclosing_disc(
00284 float x,
00285 float y,
00286 const CL_Colorf &color,
00287 CL_GraphicContext &gc);
00288
00290 void set_alignment( CL_Origin origin, float x=0, float y=0 );
00291
00293 void set_rotation_hotspot( CL_Origin origin, float x=0, float y=0 );
00294
00296 void set_translation( float x, float y );
00297
00299 void set_scale( float x, float y );
00300
00302 void set_angle(const CL_Angle &angle);
00303
00305 void rotate(const CL_Angle &angle);
00306
00308 void set_inside_test( bool value );
00309
00311 void enable_collision_info( bool points=true, bool normals=false, bool metadata=false, bool pen_depth=false);
00312
00314 void set_collision_info(const std::vector<CL_CollidingContours> &colinfo);
00315
00317 void clean_collision_info();
00318
00320 void calculate_radius();
00321
00323 void calculate_sub_circles(float radius_multiplier=3.5);
00324
00326 void calculate_smallest_enclosing_discs();
00327
00329 void calculate_convex_hulls();
00330
00334 void save(const CL_StringRef &fullname) const;
00335
00340 void save(const CL_StringRef &filename, CL_VirtualDirectory &directory) const;
00341
00345 void save(CL_IODevice &file) const;
00346
00351 bool collide( const CL_CollisionOutline &outline, bool remove_old_collision_info=true );
00352
00354 static void calculate_penetration_depth(std::vector<CL_CollidingContours> &collision_info);
00355
00359 bool point_inside( const CL_Pointf &point ) const;
00360
00364 private:
00365 CL_SharedPtr<CL_CollisionOutline_Generic> impl;
00367 };
00368