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_PixelBufferRef;
00051 class CL_OutputSourceProvider;
00052 class CL_GraphicContext;
00053 class CL_Color;
00054
00059 struct CL_CollisionPoint
00060 {
00062 CL_Pointf point;
00063
00065 CL_Pointf normal;
00066
00068 bool is_entry;
00069
00071 int contour1_line_start, contour2_line_start, contour1_line_end, contour2_line_end;
00072 };
00073
00078 struct CL_CollidingContours
00079 {
00080 const CL_Contour *contour1;
00081 const CL_Contour *contour2;
00082 bool inside;
00083 std::vector<CL_CollisionPoint> points;
00084
00085 CL_Pointf penetration_normal;
00086 float penetration_depth;
00087 CL_Pointf contour1_deep_point;
00088 CL_Pointf contour2_deep_point;
00089
00095 CL_CollidingContours(const CL_Contour *c1, const CL_Contour *c2, bool in=false) :
00096 contour1(c1),
00097 contour2(c2),
00098 inside(in),
00099 penetration_normal(0.0, 0.0),
00100 penetration_depth(0.0),
00101 contour1_deep_point(0.0, 0.0),
00102 contour2_deep_point(0.0, 0.0)
00103 {
00104 points.clear();
00105 }
00106 };
00107
00112 class CL_API_DISPLAY CL_CollisionOutline
00113 {
00116 public:
00118 CL_CollisionOutline();
00119
00125 CL_CollisionOutline(const CL_PixelBufferRef &pbuf, int alpha_limit=128, CL_OutlineAccuracy accuracy=accuracy_medium );
00126
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
00242 void optimize( unsigned char check_distance=3, float corner_angle = CL_PI / 5.0 );
00243
00252 void draw(
00253 float x,
00254 float y,
00255 const CL_Colorf &color,
00256 CL_GraphicContext &gc);
00257
00266 void draw_sub_circles(
00267 float x,
00268 float y,
00269 const CL_Colorf &color,
00270 CL_GraphicContext &gc);
00271
00280 void draw_smallest_enclosing_disc(
00281 float x,
00282 float y,
00283 const CL_Colorf &color,
00284 CL_GraphicContext &gc);
00285
00287 void set_alignment( CL_Origin origin, float x=0, float y=0 );
00288
00290 void set_rotation_hotspot( CL_Origin origin, float x=0, float y=0 );
00291
00293 void set_translation( float x, float y );
00294
00296 void set_scale( float x, float y );
00297
00299 void set_angle(const CL_Angle &angle);
00300
00302 void rotate(const CL_Angle &angle);
00303
00305 void set_inside_test( bool value );
00306
00308 void enable_collision_info( bool points=true, bool normals=false, bool metadata=false, bool pen_depth=false);
00309
00311 void set_collision_info(const std::vector<CL_CollidingContours> &colinfo);
00312
00314 void clean_collision_info();
00315
00317 void calculate_radius();
00318
00320 void calculate_sub_circles(float radius_multiplier=3.5);
00321
00323 void calculate_smallest_enclosing_discs();
00324
00326 void calculate_convex_hulls();
00327
00332 void save(const CL_StringRef &fullname) const;
00333
00338 void save(const CL_StringRef &filename, CL_VirtualDirectory &directory) const;
00339
00343 void save(CL_IODevice &file) const;
00344
00349 bool collide( const CL_CollisionOutline &outline, bool remove_old_collision_info=true );
00350
00352 static void calculate_penetration_depth(std::vector<CL_CollidingContours> &collision_info);
00353
00357 bool point_inside( const CL_Pointf &point ) const;
00358
00362 private:
00363 CL_SharedPtr<CL_CollisionOutline_Generic> impl;
00365 };
00366