1 | <?php |
||||
2 | |||||
3 | declare(strict_types=1); |
||||
4 | |||||
5 | namespace Chipmunk; |
||||
6 | |||||
7 | use Chipmunk\Exception\RuntimeException; |
||||
8 | |||||
9 | /** |
||||
10 | * A Body can be copied and pickled. Sleeping bodies that are copied will be |
||||
11 | * awake in the fresh copy. When a Body is copied any spaces, shapes or |
||||
12 | * constraints attached to the body will not be copied. |
||||
13 | * |
||||
14 | * A rigid body |
||||
15 | * |
||||
16 | * - Use forces to modify the rigid bodies if possible. This is likely to be |
||||
17 | * the most stable. |
||||
18 | * - Modifying a body’s velocity shouldn’t necessarily be avoided, but applying |
||||
19 | * large changes can cause strange results in the simulation. Experiment |
||||
20 | * freely, but be warned. |
||||
21 | * - Don’t modify a body’s position every step unless you really know what you |
||||
22 | * are doing. Otherwise you’re likely to get the position/velocity badly out |
||||
23 | * of sync. |
||||
24 | */ |
||||
25 | class Body extends AbstractFfi |
||||
26 | { |
||||
27 | /** |
||||
28 | * Alias of CP_BODY_TYPE_DYNAMIC |
||||
29 | * |
||||
30 | * A dynamic body is one that is affected by gravity, forces, and collisions. |
||||
31 | * This is the default body type. |
||||
32 | */ |
||||
33 | public const TYPE_DYNAMIC = 0; |
||||
34 | |||||
35 | /** |
||||
36 | * Alias of CP_BODY_TYPE_KINEMATIC |
||||
37 | * |
||||
38 | * A kinematic body is an infinite mass, user controlled body that is not |
||||
39 | * affected by gravity, forces or collisions. |
||||
40 | * |
||||
41 | * Instead the body only moves based on it's velocity. |
||||
42 | * |
||||
43 | * Dynamic bodies collide normally with kinematic bodies, though the |
||||
44 | * kinematic body will be unaffected. |
||||
45 | * |
||||
46 | * Collisions between two kinematic bodies, or a kinematic body and a static |
||||
47 | * body produce collision callbacks, but no collision response. |
||||
48 | */ |
||||
49 | public const TYPE_KINEMATIC = 1; |
||||
50 | |||||
51 | /** |
||||
52 | * Alias of CP_BODY_TYPE_STATIC |
||||
53 | * |
||||
54 | * A static body is a body that never (or rarely) moves. If you move a |
||||
55 | * static body, you must call one of the cpSpaceReindex*() functions. |
||||
56 | * |
||||
57 | * Chipmunk uses this information to optimize the collision detection. |
||||
58 | * |
||||
59 | * Static bodies do not produce collision callbacks when colliding with |
||||
60 | * other static bodies. |
||||
61 | */ |
||||
62 | public const TYPE_STATIC = 2; |
||||
63 | |||||
64 | /** |
||||
65 | * Create a new Body |
||||
66 | * |
||||
67 | * Mass and moment are ignored when $type is Body::TYPE_KINEMATIC or Body::TYPE_STATIC. |
||||
68 | * |
||||
69 | * Guessing the mass for a body is usually fine, but guessing a moment of |
||||
70 | * inertia can lead to a very poor simulation so it’s recommended to use |
||||
71 | * Chipmunk’s moment calculations to estimate the moment for you. |
||||
72 | * |
||||
73 | * There are two ways to set up a dynamic body. The easiest option is to |
||||
74 | * create a body with a mass and moment of 0, and set the mass or density of |
||||
75 | * each collision shape added to the body. Chipmunk will automatically |
||||
76 | * calculate the mass, moment of inertia, and center of gravity for you. |
||||
77 | * This is probably preferred in most cases. Note that these will only be |
||||
78 | * correctly calculated after the body and shape are added to a space. |
||||
79 | * |
||||
80 | * The other option is to set the mass of the body when it’s created, and |
||||
81 | * leave the mass of the shapes added to it as 0.0. This approach is more |
||||
82 | * flexible, but is not as easy to use. Don’t set the mass of both the body |
||||
83 | * and the shapes. If you do so, it will recalculate and overwrite your |
||||
84 | * custom mass value when the shapes are added to the body. |
||||
85 | * |
||||
86 | * @throws RuntimeException if specified type does not exists |
||||
87 | * |
||||
88 | */ |
||||
89 | public function __construct(float $mass = 0.0, float $moment = 0.0, int $type = self::TYPE_DYNAMIC) |
||||
90 | { |
||||
91 | parent::__construct(); |
||||
92 | |||||
93 | $this->setCData($this->getFfi()->cpBodyNew($mass, $moment)); |
||||
0 ignored issues
–
show
|
|||||
94 | |||||
95 | $this->setType($type); |
||||
96 | } |
||||
97 | |||||
98 | /** |
||||
99 | * Get a Space's static body reference |
||||
100 | */ |
||||
101 | public static function fromSpace(Space $space): self |
||||
102 | { |
||||
103 | $body = new self(); |
||||
104 | |||||
105 | $body->setCData($body->getFfi()->cpSpaceGetStaticBody($space->getCData())); |
||||
0 ignored issues
–
show
The method
cpSpaceGetStaticBody() does not exist on FFI .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||
106 | |||||
107 | return $body; |
||||
108 | } |
||||
109 | |||||
110 | /** |
||||
111 | * @throws RuntimeException if specified type does not exists |
||||
112 | */ |
||||
113 | private function assertType(int $type): void |
||||
114 | { |
||||
115 | if (!in_array($type, [self::TYPE_DYNAMIC, self::TYPE_KINEMATIC, self::TYPE_STATIC])) { |
||||
116 | throw new RuntimeException(sprintf('Unrecognized type "%s"', $type)); |
||||
117 | } |
||||
118 | } |
||||
119 | |||||
120 | /** |
||||
121 | * The type of a body (Body::TYPE_DYNAMIC, Body::TYPE_KINEMATIC or |
||||
122 | * Body::TYPE_STATIC). |
||||
123 | * |
||||
124 | * When changing an body to a dynamic body, the mass and moment of inertia |
||||
125 | * are recalculated from the shapes added tothe body. Custom calculated |
||||
126 | * moments of inertia are not preserved when changing types. |
||||
127 | * |
||||
128 | * This function cannot be called directly in a collision callback. |
||||
129 | */ |
||||
130 | public function getType(): int |
||||
131 | { |
||||
132 | return $this->getFfi()->cpBodyGetType($this->getCData()); |
||||
0 ignored issues
–
show
The method
cpBodyGetType() does not exist on FFI .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||
133 | } |
||||
134 | |||||
135 | /** |
||||
136 | * The type of a body (Body::TYPE_DYNAMIC, Body::TYPE_KINEMATIC or |
||||
137 | * Body::TYPE_STATIC). |
||||
138 | * |
||||
139 | * When changing an body to a dynamic body, the mass and moment of inertia |
||||
140 | * are recalculated from the shapes added tothe body. Custom calculated |
||||
141 | * moments of inertia are not preserved when changing types. |
||||
142 | * |
||||
143 | * This function cannot be called directly in a collision callback. |
||||
144 | * |
||||
145 | * @throws RuntimeException if specified type does not exists |
||||
146 | */ |
||||
147 | public function setType(int $type): self |
||||
148 | { |
||||
149 | $this->assertType($type); |
||||
150 | |||||
151 | $this->getFfi()->cpBodySetType($this->getCData(), $type); |
||||
0 ignored issues
–
show
The method
cpBodySetType() does not exist on FFI .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||
152 | |||||
153 | return $this; |
||||
154 | } |
||||
155 | |||||
156 | public function getMass(): float |
||||
157 | { |
||||
158 | return $this->getFfi()->cpBodyGetMass($this->getCData()); |
||||
0 ignored issues
–
show
The method
cpBodyGetMass() does not exist on FFI .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||
159 | } |
||||
160 | |||||
161 | public function setMass(float $mass): self |
||||
162 | { |
||||
163 | return $this->getFfi()->cpBodySetMass($this->getCData(), $mass); |
||||
0 ignored issues
–
show
The method
cpBodySetMass() does not exist on FFI .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||
164 | } |
||||
165 | |||||
166 | public function getMoment(): float |
||||
167 | { |
||||
168 | return $this->getFfi()->cpBodyGetMoment($this->getCData()); |
||||
0 ignored issues
–
show
The method
cpBodyGetMoment() does not exist on FFI .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||
169 | } |
||||
170 | |||||
171 | public function setMoment(float $moment): self |
||||
172 | { |
||||
173 | return $this->getFfi()->cpBodySetMoment($this->getCData(), $moment); |
||||
0 ignored issues
–
show
The method
cpBodySetMoment() does not exist on FFI .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||
174 | } |
||||
175 | } |
||||
176 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.