1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use super::shape::*;
use super::super::super::common::settings::*;
use super::super::super::common::math::*;

enum B2PolygonShape {}

extern {
    fn b2PolygonShape_Delete(ptr: *mut B2PolygonShape);
    fn b2PolygonShape_GetVertex(ptr: *mut B2PolygonShape, index: Int32) -> &Vec2;
    fn b2PolygonShape_GetVertexCount(ptr: *const B2PolygonShape) -> Int32;
    fn b2PolygonShape_New() -> *mut B2PolygonShape;
    fn b2PolygonShape_SetAsBox(ptr: *mut B2PolygonShape, hx: Float32, hy: Float32);
    fn b2PolygonShape_SetAsBox_Oriented(ptr: *mut B2PolygonShape, hx: Float32, hy: Float32, center: &Vec2, angle: Float32);
    fn b2PolygonShape_Upcast(ptr: *mut B2PolygonShape) -> *mut B2Shape;
}

/// A convex polygon. It is assumed that the interior of the polygon is to
/// the left of each edge.
/// Polygons have a maximum number of vertices equal to b2_maxPolygonVertices.
/// In most cases you should not need many vertices for a convex polygon.
pub struct PolygonShape {
    ptr: *mut B2PolygonShape,
    owned: bool,    
}

/// Cast a PolygonShape from a B2Shape.
pub fn from_shape(ptr: *mut B2Shape) -> PolygonShape {
    PolygonShape { ptr: ptr as *mut B2PolygonShape, owned: false}
}

impl Shape for PolygonShape {
    // Is the up-cast even necessary? Can't we just use self.ptr directly?
    fn handle(&self) -> *mut B2Shape {
        unsafe {
            b2PolygonShape_Upcast(self.ptr)
        }
    }
}

impl PolygonShape {

    /// Create a new PolygonShape.
    pub fn new() -> PolygonShape {
        unsafe {
            PolygonShape { ptr: b2PolygonShape_New(), owned: true }
        }
    }

    /// Get a vertex by index.
    pub fn get_vertex(&self, index: i32) -> &Vec2 {
        unsafe {
            b2PolygonShape_GetVertex(self.ptr, index)
        }
    }

    /// Get the vertex count.
    pub fn get_vertex_count(&self) -> i32 {
        unsafe {
            b2PolygonShape_GetVertexCount(self.ptr)
        }
    }

    /// Build vertices to represent an axis-aligned box centered on the local origin.
    /// @param hx the half-width.
    /// @param hy the half-height.
    pub fn set_as_box(&mut self, hx:f32, hy:f32) {
        unsafe {
            b2PolygonShape_SetAsBox(self.ptr, hx, hy);
        }
    }

    /// Build vertices to represent an oriented box.
    /// @param hx the half-width.
    /// @param hy the half-height.
    /// @param center the center of the box in local coordinates.
    /// @param angle the rotation of the box in local coordinates.
    pub fn set_as_box_oriented(&mut self, hx: f32, hy: f32, center: &Vec2, angle: f32) {
        unsafe {
            b2PolygonShape_SetAsBox_Oriented(self.ptr, hx, hy, center, angle);
        }
    }
}

impl Drop for PolygonShape {
    fn drop(&mut self) {
        if self.owned {
            unsafe {
                b2PolygonShape_Delete(self.ptr);
            }
        }
    }
}