1 /*
2  * Copyright (c) 2007-2013 Scott Lembcke and Howling Moon Software
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22 module dchip.chipmunk_types;
23 
24 import core.stdc.stdint : uintptr_t, uint32_t;
25 
26 import std.math : sqrt, sin, cos, acos, atan2, fmod, exp, pow, floor, ceil, PI, E;
27 
28 import dchip.cpVect;
29 
30 version (StdDdoc)
31 {
32     /**
33         The floating-point type used internally.
34         By default it is aliased to $(D float).
35 
36         Use the $(D CHIP_USE_DOUBLES) version switch
37         to set it to $(D double) instead. Using doubles
38         will increase precision at the cost of performance.
39     */
40     alias cpFloat = float;
41 }
42 else
43 version (CHIP_USE_DOUBLES)
44 {
45     /// The floating-point type used internally.
46     /// Use the $(D CHIP_USE_DOUBLES) version switch to enable this.
47     alias cpFloat = double;
48 }
49 else
50 {
51     ///
52     alias cpFloat = float;
53 }
54 
55 version (CHIP_USE_DOUBLES)
56 {
57     alias cpfsqrt = sqrt;
58     alias cpfsin = sin;
59     alias cpfcos = cos;
60     alias cpfacos = acos;
61     alias cpfatan2 = atan2;
62     alias cpfmod = fmod;
63     alias cpfexp = exp;
64     alias cpfpow = pow;
65     alias cpffloor = floor;
66     alias cpfceil = ceil;
67 }
68 else
69 {
70     alias cpfsqrt = sqrt;
71     alias cpfsin = sin;
72     alias cpfcos = cos;
73     alias cpfacos = acos;
74     alias cpfatan2 = atan2;
75     alias cpfmod = fmod;
76     alias cpfexp = exp;
77     alias cpfpow = pow;
78     alias cpffloor = floor;
79     alias cpfceil = ceil;
80 }
81 
82 ///
83 enum CPFLOAT_MIN = cpFloat.min_normal;
84 
85 ///
86 enum INFINITY = cpFloat.infinity;
87 
88 ///
89 alias M_PI = PI;
90 
91 ///
92 alias M_E = E;
93 
94 /// Return the max of two cpFloats.
95 cpFloat cpfmax(cpFloat a, cpFloat b)
96 {
97     return (a > b) ? a : b;
98 }
99 
100 /// Return the min of two cpFloats.
101 cpFloat cpfmin(cpFloat a, cpFloat b)
102 {
103     return (a < b) ? a : b;
104 }
105 
106 /// Return the absolute value of a cpFloat.
107 cpFloat cpfabs(cpFloat f)
108 {
109     return (f < 0) ? -f : f;
110 }
111 
112 /// Clamp $(D f) to be between $(D min) and $(D max).
113 cpFloat cpfclamp(cpFloat f, cpFloat min, cpFloat max)
114 {
115     return cpfmin(cpfmax(f, min), max);
116 }
117 
118 /// Clamp $(D f) to be between 0 and 1.
119 cpFloat cpfclamp01(cpFloat f)
120 {
121     return cpfmax(0.0f, cpfmin(f, 1.0f));
122 }
123 
124 /// Linearly interpolate (or extrapolate) between $(D f1) and $(D f2) by $(D t) percent.
125 cpFloat cpflerp(cpFloat f1, cpFloat f2, cpFloat t)
126 {
127     return f1 * (1.0f - t) + f2 * t;
128 }
129 
130 /// Linearly interpolate from $(D f1) to $(D f2) by no more than $(D d).
131 cpFloat cpflerpconst(cpFloat f1, cpFloat f2, cpFloat d)
132 {
133     return f1 + cpfclamp(f2 - f1, -d, d);
134 }
135 
136 /// Hash value type.
137 alias cpHashValue = uintptr_t;
138 
139 /// Type used internally to cache colliding object info for cpCollideShapes().
140 /// Should be at least 32 bits.
141 alias cpCollisionID = uint32_t;
142 
143 alias cpBool = bool;  /// Bools
144 enum cpTrue  = true;  /// ditto
145 enum cpFalse = false; /// ditto
146 
147 /// Type used for user data pointers.
148 alias cpDataPointer = void*;
149 
150 /// Type used for cpSpace.collision_type.
151 alias cpCollisionType = uintptr_t;
152 
153 /// Type used for cpShape.group.
154 alias cpGroup = uintptr_t;
155 
156 /// Type used for cpShape.layers.
157 alias cpLayers = uint;
158 
159 /// Type used for various timestamps in Chipmunk.
160 alias cpTimestamp = uint;
161 
162 /// Value for cpShape.group signifying that a shape is in no group.
163 enum CP_NO_GROUP = 0;
164 
165 /// Value for cpShape.layers signifying that a shape is in every layer.
166 enum CP_ALL_LAYERS = ~cast(cpLayers)0;
167 
168 /// Chipmunk's 2D vector type.
169 struct cpVect
170 {
171     cpFloat x = 0, y = 0;
172 
173     cpVect opBinary(string op : "*")(const cpFloat s)
174     {
175         return cpvmult(this, s);
176     }
177 
178     cpVect opBinary(string op : "+")(const cpVect v2)
179     {
180         return cpvadd(this, v2);
181     }
182 
183     cpVect opBinary(string op : "-")(const cpVect v2)
184     {
185         return cpvsub(this, v2);
186     }
187 
188     cpBool opEquals(const cpVect v2)
189     {
190         return cpveql(this, v2);
191     }
192 
193     cpVect opUnary(string op : "-")()
194     {
195         return cpvneg(this);
196     }
197 }
198 
199 /// Chipmunk's 2D matrix type.
200 struct cpMat2x2
201 {
202     /// Row major [[a, b][c d]]
203     cpFloat a = 0, b = 0, c = 0, d = 0;
204 }