1 /* billard.c
2 **
3 ** code for positioning the balls
4 ** Copyright (C) 2001 Florian Berger
5 ** Email: harpin_floh@yahoo.de, florian.berger@jk.uni-linz.ac.at
6 **
7 ** This program is free software; you can redistribute it and/or modify
8 ** it under the terms of the GNU General Public License Version 2 as
9 ** published by the Free Software Foundation;
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 **
20 */
21
22 #define BILLARD_C
23 #include "billard.h"
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <math.h>
27
28
29 void (*create_scene)( BallsType * balls ) = create_8ball_scene;
30 void (*create_walls)( BordersType * walls ) = create_6hole_walls;
31 void * (*billard_malloc)( size_t size ) = malloc;
32 void (*billard_free)( void * ptr ) = free;
33
setfunc_create_scene(void (* func)(BallsType * balls))34 void setfunc_create_scene( void (*func)( BallsType * balls ) )
35 {
36 create_scene=func;
37 }
38
39
setfunc_create_walls(void (* func)(BordersType * walls))40 void setfunc_create_walls( void (*func)( BordersType * walls ) )
41 {
42 create_walls=func;
43 }
44
45
setfunc_malloc_free(void * (* func_malloc)(size_t size),void (* func_free)(void * ptr))46 void setfunc_malloc_free( void * (*func_malloc)( size_t size ), void (*func_free)( void * ptr ) )
47 {
48 billard_malloc = func_malloc;
49 billard_free = func_free;
50 }
51
52
53 /* positions: */
54 /* ========== */
55 /* 11 12 13 14 15 */
56 /* 07 08 09 10 */
57 /* 04 05 06 */
58 /* 02 03 */
59 /* 01 */
60
place8ballnrs(BallsType * balls)61 void place8ballnrs( BallsType * balls )
62 {
63 int i,j,act;
64 int ok=1;
65
66 do{
67 for(i=0;i<balls->nr;i++){
68 if(i==0){
69 balls->ball[i].nr=0;
70 }else if(i==5){
71 balls->ball[i].nr=8;
72 }else{
73 int ok;
74 act = rand() % balls->nr;
75 do {
76 ok=1;
77 act = (act+1) % balls->nr;
78 DPRINTF(" trying %d\n",act);
79 for(j=0;j<i;j++){
80 if( act==balls->ball[j].nr ){ ok=0; break; }
81 }
82 if( act == 8 || act == 0 ) ok=0;
83 } while(!ok);
84 balls->ball[i].nr=act;
85 }
86 DPRINTF("i=%d: ball#=%d\n",i,balls->ball[i].nr);
87 }
88 }while(!ok);
89 for(i=0;i<balls->nr;i++){
90 DPRINTF("i=%d: ball#=%d\n",i,balls->ball[i].nr);
91 }
92 }
93
94
create_6hole_walls(BordersType * walls)95 void create_6hole_walls( BordersType * walls )
96 {
97 int i;
98
99 /* borders */
100 #ifdef USE_ADV_BORDER
101 /* borders */
102 // walls->nr=30;
103 walls->nr=32;
104 if( walls->border != NULL ) billard_free( walls->border );
105 walls->border = billard_malloc( sizeof(BorderType)*walls->nr );
106
107 /* bonds */
108 walls->border[0].pnr = 3;
109 walls->border[0].r1 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 );
110 walls->border[0].r2 = vec_xyz( +TABLE_W/2.0, +HOLE2_W/2.0, 0.0 );
111 walls->border[0].r3 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 );
112 walls->border[0].n = vec_xyz( -1.0, 0.0, 0.0 );
113
114 walls->border[1].pnr = 3;
115 walls->border[1].r1 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 );
116 walls->border[1].r2 = vec_xyz( +TABLE_W/2.0, -HOLE2_W/2.0, 0.0 );
117 walls->border[1].r3 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 );
118 walls->border[1].n = vec_xyz( -1.0, 0.0, 0.0 );
119
120 walls->border[2].pnr = 3;
121 walls->border[2].r1 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 );
122 walls->border[2].r2 = vec_xyz( -TABLE_W/2.0, +HOLE2_W/2.0, 0.0 );
123 walls->border[2].r3 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 );
124 walls->border[2].n = vec_xyz( +1.0, 0.0, 0.0 );
125
126 walls->border[3].pnr = 3;
127 walls->border[3].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 );
128 walls->border[3].r2 = vec_xyz( -TABLE_W/2.0, -HOLE2_W/2.0, 0.0 );
129 walls->border[3].r3 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 );
130 walls->border[3].n = vec_xyz( +1.0, 0.0, 0.0 );
131
132 walls->border[4].pnr = 3;
133 walls->border[4].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, -BALL_D/2.0 );
134 walls->border[4].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, +TABLE_L/2.0, 0.0 );
135 walls->border[4].r3 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, BALL_D/2.0 );
136 walls->border[4].n = vec_xyz( 0.0, -1.0, 0.0 );
137
138 walls->border[5].pnr = 3;
139 walls->border[5].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, -BALL_D/2.0 );
140 walls->border[5].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, -TABLE_L/2.0, 0.0 );
141 walls->border[5].r3 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, BALL_D/2.0 );
142 walls->border[5].n = vec_xyz( 0.0, +1.0, 0.0 );
143
144 /* edges */
145 /* upper right */
146 walls->border[6].pnr = 2;
147 walls->border[6].r1 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 );
148 walls->border[6].r2 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 );
149 walls->border[18].pnr = 3;
150 walls->border[18].r1 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 );
151 walls->border[18].r2 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 );
152 walls->border[18].r3 = vec_xyz( +TABLE_W/2.0+1.0, +TABLE_L/2.0-HOLE1_W/SQR2+HOLE1_TAN, 0.0 );
153 walls->border[18].n = vec_unit(vec_cross(vec_diff(walls->border[18].r2,walls->border[18].r1),vec_diff(walls->border[18].r3,walls->border[18].r1)));
154
155 /* upper right */
156 walls->border[7].pnr = 2;
157 walls->border[7].r1 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, +TABLE_L/2.0, -BALL_D/2.0 );
158 walls->border[7].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, +TABLE_L/2.0, BALL_D/2.0 );
159 walls->border[19].pnr = 3;
160 walls->border[19].r1 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, +TABLE_L/2.0, -BALL_D/2.0 );
161 walls->border[19].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, +TABLE_L/2.0, BALL_D/2.0 );
162 walls->border[19].r3 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2+HOLE1_TAN, +TABLE_L/2.0+1.0, 0.0 );
163 walls->border[19].n = vec_unit(vec_cross(vec_diff(walls->border[19].r1,walls->border[19].r2),vec_diff(walls->border[19].r3,walls->border[19].r1)));
164
165 /* upper left */
166 walls->border[8].pnr = 2;
167 walls->border[8].r1 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 );
168 walls->border[8].r2 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 );
169 walls->border[20].pnr = 3;
170 walls->border[20].r1 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 );
171 walls->border[20].r2 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 );
172 walls->border[20].r3 = vec_xyz( -TABLE_W/2.0-1.0, +TABLE_L/2.0-HOLE1_W/SQR2+HOLE1_TAN, 0.0 );
173 walls->border[20].n = vec_unit(vec_cross(vec_diff(walls->border[20].r1,walls->border[20].r2),vec_diff(walls->border[20].r3,walls->border[20].r1)));
174
175 /* upper left */
176 walls->border[9].pnr = 2;
177 walls->border[9].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, -BALL_D/2.0 );
178 walls->border[9].r2 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, BALL_D/2.0 );
179 walls->border[21].pnr = 3;
180 walls->border[21].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, -BALL_D/2.0 );
181 walls->border[21].r2 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, BALL_D/2.0 );
182 walls->border[21].r3 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2-HOLE1_TAN, +TABLE_L/2.0+1.0, 0.0 );
183 walls->border[21].n = vec_unit(vec_cross(vec_diff(walls->border[21].r2,walls->border[21].r1),vec_diff(walls->border[21].r3,walls->border[21].r1)));
184
185 /* lower right */
186 walls->border[10].pnr = 2;
187 walls->border[10].r1 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 );
188 walls->border[10].r2 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 );
189 walls->border[22].pnr = 3;
190 walls->border[22].r1 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 );
191 walls->border[22].r2 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 );
192 walls->border[22].r3 = vec_xyz( +TABLE_W/2.0+1.0, -TABLE_L/2.0+HOLE1_W/SQR2-HOLE1_TAN, 0.0 );
193 walls->border[22].n = vec_unit(vec_cross(vec_diff(walls->border[22].r1,walls->border[22].r2),vec_diff(walls->border[22].r3,walls->border[22].r1)));
194
195 /* lower right */
196 walls->border[11].pnr = 2;
197 walls->border[11].r1 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, -TABLE_L/2.0, -BALL_D/2.0 );
198 walls->border[11].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, -TABLE_L/2.0, BALL_D/2.0 );
199 walls->border[23].pnr = 3;
200 walls->border[23].r1 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, -TABLE_L/2.0, -BALL_D/2.0 );
201 walls->border[23].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, -TABLE_L/2.0, BALL_D/2.0 );
202 walls->border[23].r3 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2+HOLE1_TAN, -TABLE_L/2.0-1.0, 0.0 );
203 walls->border[23].n = vec_unit(vec_cross(vec_diff(walls->border[23].r2,walls->border[23].r1),vec_diff(walls->border[23].r3,walls->border[23].r1)));
204
205 /* lower left */
206 walls->border[12].pnr = 2;
207 walls->border[12].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 );
208 walls->border[12].r2 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 );
209 walls->border[24].pnr = 3;
210 walls->border[24].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 );
211 walls->border[24].r2 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 );
212 walls->border[24].r3 = vec_xyz( -TABLE_W/2.0-1.0, -TABLE_L/2.0+HOLE1_W/SQR2-HOLE1_TAN, 0.0 );
213 walls->border[24].n = vec_unit(vec_cross(vec_diff(walls->border[24].r2,walls->border[24].r1),vec_diff(walls->border[24].r3,walls->border[24].r1)));
214
215 /* lower left */
216 walls->border[13].pnr = 2;
217 walls->border[13].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, -BALL_D/2.0 );
218 walls->border[13].r2 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, BALL_D/2.0 );
219 walls->border[25].pnr = 3;
220 walls->border[25].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, -BALL_D/2.0 );
221 walls->border[25].r2 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, BALL_D/2.0 );
222 walls->border[25].r3 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2-HOLE1_TAN, -TABLE_L/2.0-1.0, 0.0 );
223 walls->border[25].n = vec_unit(vec_cross(vec_diff(walls->border[25].r1,walls->border[25].r2),vec_diff(walls->border[25].r3,walls->border[25].r1)));
224
225 /* middle left */
226 walls->border[14].pnr = 2;
227 walls->border[14].r1 = vec_xyz( -TABLE_W/2.0, HOLE2_W/2.0, -BALL_D/2.0 );
228 walls->border[14].r2 = vec_xyz( -TABLE_W/2.0, HOLE2_W/2.0, BALL_D/2.0 );
229 walls->border[26].pnr = 3;
230 walls->border[26].r1 = vec_xyz( -TABLE_W/2.0, HOLE2_W/2.0, -BALL_D/2.0 );
231 walls->border[26].r2 = vec_xyz( -TABLE_W/2.0, HOLE2_W/2.0, BALL_D/2.0 );
232 walls->border[26].r3 = vec_xyz( -TABLE_W/2.0-1.0, HOLE2_W/2.0-HOLE2_TAN, 0.0 );
233 walls->border[26].n = vec_unit(vec_cross(vec_diff(walls->border[26].r2,walls->border[26].r1),vec_diff(walls->border[26].r3,walls->border[26].r1)));
234
235 /* middle left */
236 walls->border[15].pnr = 2;
237 walls->border[15].r1 = vec_xyz( -TABLE_W/2.0, -HOLE2_W/2.0, -BALL_D/2.0 );
238 walls->border[15].r2 = vec_xyz( -TABLE_W/2.0, -HOLE2_W/2.0, BALL_D/2.0 );
239 walls->border[27].pnr = 3;
240 walls->border[27].r1 = vec_xyz( -TABLE_W/2.0, -HOLE2_W/2.0, -BALL_D/2.0 );
241 walls->border[27].r2 = vec_xyz( -TABLE_W/2.0, -HOLE2_W/2.0, BALL_D/2.0 );
242 walls->border[27].r3 = vec_xyz( -TABLE_W/2.0-1.0, -HOLE2_W/2.0+HOLE2_TAN, 0.0 );
243 walls->border[27].n = vec_unit(vec_cross(vec_diff(walls->border[27].r1,walls->border[27].r2),vec_diff(walls->border[27].r3,walls->border[27].r1)));
244
245 /* middle right */
246 walls->border[16].pnr = 2;
247 walls->border[16].r1 = vec_xyz( +TABLE_W/2.0, HOLE2_W/2.0, -BALL_D/2.0 );
248 walls->border[16].r2 = vec_xyz( +TABLE_W/2.0, HOLE2_W/2.0, BALL_D/2.0 );
249 walls->border[28].pnr = 3;
250 walls->border[28].r1 = vec_xyz( +TABLE_W/2.0, HOLE2_W/2.0, -BALL_D/2.0 );
251 walls->border[28].r2 = vec_xyz( +TABLE_W/2.0, HOLE2_W/2.0, BALL_D/2.0 );
252 walls->border[28].r3 = vec_xyz( +TABLE_W/2.0+1.0, HOLE2_W/2.0-HOLE2_TAN, 0.0 );
253 walls->border[28].n = vec_unit(vec_cross(vec_diff(walls->border[28].r1,walls->border[28].r2),vec_diff(walls->border[28].r3,walls->border[28].r1)));
254
255 /* middle right */
256 walls->border[17].pnr = 2;
257 walls->border[17].r1 = vec_xyz( +TABLE_W/2.0, -HOLE2_W/2.0, -BALL_D/2.0 );
258 walls->border[17].r2 = vec_xyz( +TABLE_W/2.0, -HOLE2_W/2.0, BALL_D/2.0 );
259 walls->border[29].pnr = 3;
260 walls->border[29].r1 = vec_xyz( +TABLE_W/2.0, -HOLE2_W/2.0, -BALL_D/2.0 );
261 walls->border[29].r2 = vec_xyz( +TABLE_W/2.0, -HOLE2_W/2.0, BALL_D/2.0 );
262 walls->border[29].r3 = vec_xyz( +TABLE_W/2.0+1.0, -HOLE2_W/2.0+HOLE2_TAN, 0.0 );
263 walls->border[29].n = vec_unit(vec_cross(vec_diff(walls->border[29].r2,walls->border[29].r1),vec_diff(walls->border[29].r3,walls->border[29].r1)));
264
265 /* friction constants and loss factors */
266 for(i=0;i<walls->nr;i++){
267 walls->border[i].mu = 0.1;
268 walls->border[i].loss0 = 0.2;
269 walls->border[i].loss_max = 0.5;
270 walls->border[i].loss_wspeed = 4.0; /* [m/s] */
271 }
272
273 /* table surface */
274 #define TABLE_W2 (TABLE_W-BALL_D*0.9)
275 #define TABLE_L2 (TABLE_L-BALL_D*0.9)
276 walls->border[30].pnr = 3;
277 walls->border[30].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0, -BALL_D/2.0-0.0001 );
278 walls->border[30].r2 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0, -BALL_D/2.0-0.0001 );
279 walls->border[30].r3 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0, -BALL_D/2.0-0.0001 );
280 walls->border[30].n = vec_xyz( 0.0, 0.0, 1.0 );
281
282 walls->border[31].pnr = 3;
283 walls->border[31].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0, -BALL_D/2.0-0.0001 );
284 walls->border[31].r3 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0, -BALL_D/2.0-0.0001 );
285 walls->border[31].r2 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0, -BALL_D/2.0-0.0001 );
286 walls->border[31].n = vec_xyz( 0.0, 0.0, 1.0 );
287 #undef TABLE_W2
288 #undef TABLE_L2
289
290 walls->border[30].mu = 0.2;
291 walls->border[30].loss0 = 0.6;
292 walls->border[30].loss_max = 0.99;
293 walls->border[30].loss_wspeed = 1.5;
294 walls->border[31].mu = 0.2;
295 walls->border[31].loss0 = 0.6;
296 walls->border[31].loss_max = 0.99;
297 walls->border[31].loss_wspeed = 1.5;
298
299 #else
300 /* borders */
301 walls->nr=4;
302 walls->border = billard_malloc(sizeof(BorderType)*walls->nr);
303 walls->border[0].r = vec_xyz( +TABLE_W/2.0, 0.0, 0.0 );
304 walls->border[0].n = vec_xyz( -1.0, 0.0, 0.0 );
305 walls->border[1].r = vec_xyz( -TABLE_W/2.0, 0.0, 0.0 );
306 walls->border[1].n = vec_xyz( +1.0, 0.0, 0.0 );
307 walls->border[2].r = vec_xyz( 0.0, +TABLE_L/2.0, 0.0 );
308 walls->border[2].n = vec_xyz( 0.0, -1.0, 0.0 );
309 walls->border[3].r = vec_xyz( 0.0, -TABLE_L/2.0, 0.0 );
310 walls->border[3].n = vec_xyz( 0.0, +1.0, 0.0 );
311 #endif
312
313 /* holes */
314 walls->holenr = 6;
315 if( walls->hole != NULL ) billard_free( walls->hole );
316 walls->hole = billard_malloc(sizeof(HoleType)*walls->holenr);
317 /* middle right */
318 walls->hole[0].aim = vec_xyz( +TABLE_W/2.0-HOLE2_AIMOFFS, 0.0, 0.0 );
319 walls->hole[0].pos = vec_xyz( +TABLE_W/2.0+HOLE2_XYOFFS, 0.0, 0.0 );
320 walls->hole[0].r = HOLE2_R;
321 /* middle left */
322 walls->hole[1].aim = vec_xyz( -TABLE_W/2.0+HOLE2_AIMOFFS, 0.0, 0.0 );
323 walls->hole[1].pos = vec_xyz( -TABLE_W/2.0-HOLE2_XYOFFS, 0.0, 0.0 );
324 walls->hole[1].r = HOLE2_R;
325 /* upper right */
326 walls->hole[2].aim = vec_xyz( +TABLE_W/2.0-HOLE1_AIMOFFS, +TABLE_L/2.0-HOLE1_AIMOFFS, 0.0 );
327 walls->hole[2].pos = vec_xyz( +TABLE_W/2.0+HOLE1_XYOFFS, +TABLE_L/2.0+HOLE1_XYOFFS, 0.0 );
328 walls->hole[2].r = HOLE1_R;
329 /* upper left */
330 walls->hole[3].aim = vec_xyz( -TABLE_W/2.0+HOLE1_AIMOFFS, +TABLE_L/2.0-HOLE1_AIMOFFS, 0.0 );
331 walls->hole[3].pos = vec_xyz( -TABLE_W/2.0-HOLE1_XYOFFS, +TABLE_L/2.0+HOLE1_XYOFFS, 0.0 );
332 walls->hole[3].r = HOLE1_R;
333 /* lower left */
334 walls->hole[4].aim = vec_xyz( -TABLE_W/2.0+HOLE1_AIMOFFS, -TABLE_L/2.0-HOLE1_AIMOFFS, 0.0 );
335 walls->hole[4].pos = vec_xyz( -TABLE_W/2.0-HOLE1_XYOFFS, -TABLE_L/2.0-HOLE1_XYOFFS, 0.0 );
336 walls->hole[4].r = HOLE1_R;
337 /* lower right */
338 walls->hole[5].aim = vec_xyz( +TABLE_W/2.0-HOLE1_AIMOFFS, -TABLE_L/2.0+HOLE1_AIMOFFS, 0.0 );
339 walls->hole[5].pos = vec_xyz( +TABLE_W/2.0+HOLE1_XYOFFS, -TABLE_L/2.0-HOLE1_XYOFFS, 0.0 );
340 walls->hole[5].r = HOLE1_R;
341 }
342
343
create_6hole_walls_snooker(BordersType * walls)344 void create_6hole_walls_snooker( BordersType * walls )
345 {
346 int i;
347
348 /* borders */
349 #ifdef USE_ADV_BORDER
350 /* borders */
351 // walls->nr=30;
352 walls->nr=32;
353 if( walls->border != NULL ) billard_free( walls->border );
354 walls->border = billard_malloc( sizeof(BorderType)*walls->nr );
355
356 /* bonds */
357 walls->border[0].pnr = 3;
358 walls->border[0].r1 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 );
359 walls->border[0].r2 = vec_xyz( +TABLE_W/2.0, +HOLE2_W/2.0, 0.0 );
360 walls->border[0].r3 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 );
361 walls->border[0].n = vec_xyz( -1.0, 0.0, 0.0 );
362
363 walls->border[1].pnr = 3;
364 walls->border[1].r1 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 );
365 walls->border[1].r2 = vec_xyz( +TABLE_W/2.0, -HOLE2_W/2.0, 0.0 );
366 walls->border[1].r3 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 );
367 walls->border[1].n = vec_xyz( -1.0, 0.0, 0.0 );
368
369 walls->border[2].pnr = 3;
370 walls->border[2].r1 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 );
371 walls->border[2].r2 = vec_xyz( -TABLE_W/2.0, +HOLE2_W/2.0, 0.0 );
372 walls->border[2].r3 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 );
373 walls->border[2].n = vec_xyz( +1.0, 0.0, 0.0 );
374
375 walls->border[3].pnr = 3;
376 walls->border[3].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 );
377 walls->border[3].r2 = vec_xyz( -TABLE_W/2.0, -HOLE2_W/2.0, 0.0 );
378 walls->border[3].r3 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 );
379 walls->border[3].n = vec_xyz( +1.0, 0.0, 0.0 );
380
381 walls->border[4].pnr = 3;
382 walls->border[4].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, -BALL_D/2.0 );
383 walls->border[4].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, +TABLE_L/2.0, 0.0 );
384 walls->border[4].r3 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, BALL_D/2.0 );
385 walls->border[4].n = vec_xyz( 0.0, -1.0, 0.0 );
386
387 walls->border[5].pnr = 3;
388 walls->border[5].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, -BALL_D/2.0 );
389 walls->border[5].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, -TABLE_L/2.0, 0.0 );
390 walls->border[5].r3 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, BALL_D/2.0 );
391 walls->border[5].n = vec_xyz( 0.0, +1.0, 0.0 );
392
393 /* edges */
394 /* upper right */
395 walls->border[6].pnr = 2;
396 walls->border[6].r1 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 );
397 walls->border[6].r2 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 );
398 walls->border[18].pnr = 3;
399 walls->border[18].r1 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 );
400 walls->border[18].r2 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 );
401 walls->border[18].r3 = vec_xyz( +TABLE_W/2.0+1.0, +TABLE_L/2.0-HOLE1_W/SQR2+HOLE1_TAN, 0.0 );
402 walls->border[18].n = vec_unit(vec_cross(vec_diff(walls->border[18].r2,walls->border[18].r1),vec_diff(walls->border[18].r3,walls->border[18].r1)));
403
404 /* upper right */
405 walls->border[7].pnr = 2;
406 walls->border[7].r1 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, +TABLE_L/2.0, -BALL_D/2.0 );
407 walls->border[7].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, +TABLE_L/2.0, BALL_D/2.0 );
408 walls->border[19].pnr = 3;
409 walls->border[19].r1 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, +TABLE_L/2.0, -BALL_D/2.0 );
410 walls->border[19].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, +TABLE_L/2.0, BALL_D/2.0 );
411 walls->border[19].r3 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2+HOLE1_TAN, +TABLE_L/2.0+1.0, 0.0 );
412 walls->border[19].n = vec_unit(vec_cross(vec_diff(walls->border[19].r1,walls->border[19].r2),vec_diff(walls->border[19].r3,walls->border[19].r1)));
413
414 /* upper left */
415 walls->border[8].pnr = 2;
416 walls->border[8].r1 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 );
417 walls->border[8].r2 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 );
418 walls->border[20].pnr = 3;
419 walls->border[20].r1 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 );
420 walls->border[20].r2 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 );
421 walls->border[20].r3 = vec_xyz( -TABLE_W/2.0-1.0, +TABLE_L/2.0-HOLE1_W/SQR2+HOLE1_TAN, 0.0 );
422 walls->border[20].n = vec_unit(vec_cross(vec_diff(walls->border[20].r1,walls->border[20].r2),vec_diff(walls->border[20].r3,walls->border[20].r1)));
423
424 /* upper left */
425 walls->border[9].pnr = 2;
426 walls->border[9].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, -BALL_D/2.0 );
427 walls->border[9].r2 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, BALL_D/2.0 );
428 walls->border[21].pnr = 3;
429 walls->border[21].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, -BALL_D/2.0 );
430 walls->border[21].r2 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, BALL_D/2.0 );
431 walls->border[21].r3 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2-HOLE1_TAN, +TABLE_L/2.0+1.0, 0.0 );
432 walls->border[21].n = vec_unit(vec_cross(vec_diff(walls->border[21].r2,walls->border[21].r1),vec_diff(walls->border[21].r3,walls->border[21].r1)));
433
434 /* lower right */
435 walls->border[10].pnr = 2;
436 walls->border[10].r1 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 );
437 walls->border[10].r2 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 );
438 walls->border[22].pnr = 3;
439 walls->border[22].r1 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 );
440 walls->border[22].r2 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 );
441 walls->border[22].r3 = vec_xyz( +TABLE_W/2.0+1.0, -TABLE_L/2.0+HOLE1_W/SQR2-HOLE1_TAN, 0.0 );
442 walls->border[22].n = vec_unit(vec_cross(vec_diff(walls->border[22].r1,walls->border[22].r2),vec_diff(walls->border[22].r3,walls->border[22].r1)));
443
444 /* lower right */
445 walls->border[11].pnr = 2;
446 walls->border[11].r1 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, -TABLE_L/2.0, -BALL_D/2.0 );
447 walls->border[11].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, -TABLE_L/2.0, BALL_D/2.0 );
448 walls->border[23].pnr = 3;
449 walls->border[23].r1 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, -TABLE_L/2.0, -BALL_D/2.0 );
450 walls->border[23].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, -TABLE_L/2.0, BALL_D/2.0 );
451 walls->border[23].r3 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2+HOLE1_TAN, -TABLE_L/2.0-1.0, 0.0 );
452 walls->border[23].n = vec_unit(vec_cross(vec_diff(walls->border[23].r2,walls->border[23].r1),vec_diff(walls->border[23].r3,walls->border[23].r1)));
453
454 /* lower left */
455 walls->border[12].pnr = 2;
456 walls->border[12].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 );
457 walls->border[12].r2 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 );
458 walls->border[24].pnr = 3;
459 walls->border[24].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 );
460 walls->border[24].r2 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 );
461 walls->border[24].r3 = vec_xyz( -TABLE_W/2.0-1.0, -TABLE_L/2.0+HOLE1_W/SQR2-HOLE1_TAN, 0.0 );
462 walls->border[24].n = vec_unit(vec_cross(vec_diff(walls->border[24].r2,walls->border[24].r1),vec_diff(walls->border[24].r3,walls->border[24].r1)));
463
464 /* lower left */
465 walls->border[13].pnr = 2;
466 walls->border[13].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, -BALL_D/2.0 );
467 walls->border[13].r2 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, BALL_D/2.0 );
468 walls->border[25].pnr = 3;
469 walls->border[25].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, -BALL_D/2.0 );
470 walls->border[25].r2 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, BALL_D/2.0 );
471 walls->border[25].r3 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2-HOLE1_TAN, -TABLE_L/2.0-1.0, 0.0 );
472 walls->border[25].n = vec_unit(vec_cross(vec_diff(walls->border[25].r1,walls->border[25].r2),vec_diff(walls->border[25].r3,walls->border[25].r1)));
473
474 /* middle left */
475 walls->border[14].pnr = 2;
476 walls->border[14].r1 = vec_xyz( -TABLE_W/2.0, HOLE2_W/2.0, -BALL_D/2.0 );
477 walls->border[14].r2 = vec_xyz( -TABLE_W/2.0, HOLE2_W/2.0, BALL_D/2.0 );
478 walls->border[26].pnr = 3;
479 walls->border[26].r1 = vec_xyz( -TABLE_W/2.0, HOLE2_W/2.0, -BALL_D/2.0 );
480 walls->border[26].r2 = vec_xyz( -TABLE_W/2.0, HOLE2_W/2.0, BALL_D/2.0 );
481 walls->border[26].r3 = vec_xyz( -TABLE_W/2.0-1.0, HOLE2_W/2.0-HOLE2_TAN, 0.0 );
482 walls->border[26].n = vec_unit(vec_cross(vec_diff(walls->border[26].r2,walls->border[26].r1),vec_diff(walls->border[26].r3,walls->border[26].r1)));
483
484 /* middle left */
485 walls->border[15].pnr = 2;
486 walls->border[15].r1 = vec_xyz( -TABLE_W/2.0, -HOLE2_W/2.0, -BALL_D/2.0 );
487 walls->border[15].r2 = vec_xyz( -TABLE_W/2.0, -HOLE2_W/2.0, BALL_D/2.0 );
488 walls->border[27].pnr = 3;
489 walls->border[27].r1 = vec_xyz( -TABLE_W/2.0, -HOLE2_W/2.0, -BALL_D/2.0 );
490 walls->border[27].r2 = vec_xyz( -TABLE_W/2.0, -HOLE2_W/2.0, BALL_D/2.0 );
491 walls->border[27].r3 = vec_xyz( -TABLE_W/2.0-1.0, -HOLE2_W/2.0+HOLE2_TAN, 0.0 );
492 walls->border[27].n = vec_unit(vec_cross(vec_diff(walls->border[27].r1,walls->border[27].r2),vec_diff(walls->border[27].r3,walls->border[27].r1)));
493
494 /* middle right */
495 walls->border[16].pnr = 2;
496 walls->border[16].r1 = vec_xyz( +TABLE_W/2.0, HOLE2_W/2.0, -BALL_D/2.0 );
497 walls->border[16].r2 = vec_xyz( +TABLE_W/2.0, HOLE2_W/2.0, BALL_D/2.0 );
498 walls->border[28].pnr = 3;
499 walls->border[28].r1 = vec_xyz( +TABLE_W/2.0, HOLE2_W/2.0, -BALL_D/2.0 );
500 walls->border[28].r2 = vec_xyz( +TABLE_W/2.0, HOLE2_W/2.0, BALL_D/2.0 );
501 walls->border[28].r3 = vec_xyz( +TABLE_W/2.0+1.0, HOLE2_W/2.0-HOLE2_TAN, 0.0 );
502 walls->border[28].n = vec_unit(vec_cross(vec_diff(walls->border[28].r1,walls->border[28].r2),vec_diff(walls->border[28].r3,walls->border[28].r1)));
503
504 /* middle right */
505 walls->border[17].pnr = 2;
506 walls->border[17].r1 = vec_xyz( +TABLE_W/2.0, -HOLE2_W/2.0, -BALL_D/2.0 );
507 walls->border[17].r2 = vec_xyz( +TABLE_W/2.0, -HOLE2_W/2.0, BALL_D/2.0 );
508 walls->border[29].pnr = 3;
509 walls->border[29].r1 = vec_xyz( +TABLE_W/2.0, -HOLE2_W/2.0, -BALL_D/2.0 );
510 walls->border[29].r2 = vec_xyz( +TABLE_W/2.0, -HOLE2_W/2.0, BALL_D/2.0 );
511 walls->border[29].r3 = vec_xyz( +TABLE_W/2.0+1.0, -HOLE2_W/2.0+HOLE2_TAN, 0.0 );
512 walls->border[29].n = vec_unit(vec_cross(vec_diff(walls->border[29].r2,walls->border[29].r1),vec_diff(walls->border[29].r3,walls->border[29].r1)));
513
514 /* friction constants and loss factors */
515 for(i=0;i<walls->nr;i++){
516 walls->border[i].mu = 0.1;
517 walls->border[i].loss0 = 0.2;
518 walls->border[i].loss_max = 0.5;
519 walls->border[i].loss_wspeed = 4.0; /* [m/s] */
520 }
521
522 /* table surface */
523 #define TABLE_W2 (TABLE_W-BALL_D*0.9)
524 #define TABLE_L2 (TABLE_L-BALL_D*0.9)
525 walls->border[30].pnr = 3;
526 walls->border[30].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0, -BALL_D/2.0-0.0001 );
527 walls->border[30].r2 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0, -BALL_D/2.0-0.0001 );
528 walls->border[30].r3 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0, -BALL_D/2.0-0.0001 );
529 walls->border[30].n = vec_xyz( 0.0, 0.0, 1.0 );
530
531 walls->border[31].pnr = 3;
532 walls->border[31].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0, -BALL_D/2.0-0.0001 );
533 walls->border[31].r3 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0, -BALL_D/2.0-0.0001 );
534 walls->border[31].r2 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0, -BALL_D/2.0-0.0001 );
535 walls->border[31].n = vec_xyz( 0.0, 0.0, 1.0 );
536 #undef TABLE_W2
537 #undef TABLE_L2
538
539 walls->border[30].mu = 0.2;
540 walls->border[30].loss0 = 0.6;
541 walls->border[30].loss_max = 0.99;
542 walls->border[30].loss_wspeed = 1.5;
543 walls->border[31].mu = 0.2;
544 walls->border[31].loss0 = 0.6;
545 walls->border[31].loss_max = 0.99;
546 walls->border[31].loss_wspeed = 1.5;
547
548 #else
549 /* borders */
550 walls->nr=4;
551 walls->border = billard_malloc(sizeof(BorderType)*walls->nr);
552 walls->border[0].r = vec_xyz( +TABLE_W/2.0, 0.0, 0.0 );
553 walls->border[0].n = vec_xyz( -1.0, 0.0, 0.0 );
554 walls->border[1].r = vec_xyz( -TABLE_W/2.0, 0.0, 0.0 );
555 walls->border[1].n = vec_xyz( +1.0, 0.0, 0.0 );
556 walls->border[2].r = vec_xyz( 0.0, +TABLE_L/2.0, 0.0 );
557 walls->border[2].n = vec_xyz( 0.0, -1.0, 0.0 );
558 walls->border[3].r = vec_xyz( 0.0, -TABLE_L/2.0, 0.0 );
559 walls->border[3].n = vec_xyz( 0.0, +1.0, 0.0 );
560 #endif
561
562 /* holes */
563 walls->holenr = 6;
564 if( walls->hole != NULL ) billard_free( walls->hole );
565 walls->hole = billard_malloc(sizeof(HoleType)*walls->holenr);
566 /* middle right */
567 walls->hole[0].aim = vec_xyz( +TABLE_W/2.0-HOLE2_AIMOFFS, 0.0, 0.0 );
568 walls->hole[0].pos = vec_xyz( +TABLE_W/2.0+HOLE2_XYOFFS, 0.0, 0.0 );
569 walls->hole[0].r = HOLE2_R;
570 /* middle left */
571 walls->hole[1].aim = vec_xyz( -TABLE_W/2.0+HOLE2_AIMOFFS, 0.0, 0.0 );
572 walls->hole[1].pos = vec_xyz( -TABLE_W/2.0-HOLE2_XYOFFS, 0.0, 0.0 );
573 walls->hole[1].r = HOLE2_R;
574 /* upper right */
575 walls->hole[2].aim = vec_xyz( +TABLE_W/2.0-HOLE1_AIMOFFS, +TABLE_L/2.0-HOLE1_AIMOFFS, 0.0 );
576 walls->hole[2].pos = vec_xyz( +TABLE_W/2.0+HOLE1_XYOFFS, +TABLE_L/2.0+HOLE1_XYOFFS, 0.0 );
577 walls->hole[2].r = HOLE1_R;
578 /* upper left */
579 walls->hole[3].aim = vec_xyz( -TABLE_W/2.0+HOLE1_AIMOFFS, +TABLE_L/2.0-HOLE1_AIMOFFS, 0.0 );
580 walls->hole[3].pos = vec_xyz( -TABLE_W/2.0-HOLE1_XYOFFS, +TABLE_L/2.0+HOLE1_XYOFFS, 0.0 );
581 walls->hole[3].r = HOLE1_R;
582 /* lower left */
583 walls->hole[4].aim = vec_xyz( -TABLE_W/2.0+HOLE1_AIMOFFS, -TABLE_L/2.0-HOLE1_AIMOFFS, 0.0 );
584 walls->hole[4].pos = vec_xyz( -TABLE_W/2.0-HOLE1_XYOFFS, -TABLE_L/2.0-HOLE1_XYOFFS, 0.0 );
585 walls->hole[4].r = HOLE1_R;
586 /* lower right */
587 walls->hole[5].aim = vec_xyz( +TABLE_W/2.0-HOLE1_AIMOFFS, -TABLE_L/2.0+HOLE1_AIMOFFS, 0.0 );
588 walls->hole[5].pos = vec_xyz( +TABLE_W/2.0+HOLE1_XYOFFS, -TABLE_L/2.0-HOLE1_XYOFFS, 0.0 );
589 walls->hole[5].r = HOLE1_R;
590 }
591
592
create_0hole_walls(BordersType * walls)593 void create_0hole_walls( BordersType * walls )
594 {
595 int i;
596
597 /* borders */
598 walls->nr=6;
599 if( walls->border != NULL ) billard_free( walls->border );
600 walls->border = billard_malloc( sizeof(BorderType)*walls->nr );
601
602 /* bonds */
603 /* walls->border[0].pnr = 3;
604 walls->border[0].r1 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0, -BALL_D/2.0 );
605 walls->border[0].r2 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0, 0.0 );
606 walls->border[0].r3 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0, BALL_D/2.0 );
607 walls->border[0].n = vec_xyz( -1.0, 0.0, 0.0 );
608
609 walls->border[1].pnr = 3;
610 walls->border[1].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0, BALL_D/2.0 );
611 walls->border[1].r2 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0, 0.0 );
612 walls->border[1].r3 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0, -BALL_D/2.0 );
613 walls->border[1].n = vec_xyz( +1.0, 0.0, 0.0 );
614
615 walls->border[2].pnr = 3;
616 walls->border[2].r1 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0, -BALL_D/2.0 );
617 walls->border[2].r2 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0, 0.0 );
618 walls->border[2].r3 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0, BALL_D/2.0 );
619 walls->border[2].n = vec_xyz( 0.0, -1.0, 0.0 );
620
621 walls->border[3].pnr = 3;
622 walls->border[3].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0, -BALL_D/2.0 );
623 walls->border[3].r2 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0, 0.0 );
624 walls->border[3].r3 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0, BALL_D/2.0 );
625 walls->border[3].n = vec_xyz( 0.0, +1.0, 0.0 );*/
626
627 walls->border[0].pnr = 2;
628 walls->border[0].r1 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0, options_jump_shots ? 0.14*BALL_D : 0.0 );
629 walls->border[0].r2 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0, options_jump_shots ? 0.14*BALL_D : 0.0 );
630
631 walls->border[1].pnr = 2;
632 walls->border[1].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0, options_jump_shots ? 0.14*BALL_D : 0.0 );
633 walls->border[1].r2 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0, options_jump_shots ? 0.14*BALL_D : 0.0 );
634
635 walls->border[2].pnr = 2;
636 walls->border[2].r1 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0, options_jump_shots ? 0.14*BALL_D : 0.0 );
637 walls->border[2].r2 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0, options_jump_shots ? 0.14*BALL_D : 0.0 );
638
639 walls->border[3].pnr = 2;
640 walls->border[3].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0, options_jump_shots ? 0.14*BALL_D : 0.0 );
641 walls->border[3].r2 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0, options_jump_shots ? 0.14*BALL_D : 0.0 );
642
643 for(i=0;i<walls->nr;i++){
644 walls->border[i].mu = 0.12;
645 walls->border[i].loss0 = 0.2;
646 walls->border[i].loss_max = 0.5;
647 walls->border[i].loss_wspeed = 4.0; /* [m/s] */
648 }
649
650 /* table surface */
651 walls->border[4].pnr = 3;
652 walls->border[4].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0, -BALL_D/2.0-0.0001 );
653 walls->border[4].r2 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0, -BALL_D/2.0-0.0001 );
654 walls->border[4].r3 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0, -BALL_D/2.0-0.0001 );
655 walls->border[4].n = vec_xyz( 0.0, 0.0, 1.0 );
656
657 walls->border[5].pnr = 3;
658 walls->border[5].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0, -BALL_D/2.0-0.0001 );
659 walls->border[5].r3 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0, -BALL_D/2.0-0.0001 );
660 walls->border[5].r2 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0, -BALL_D/2.0-0.0001 );
661 walls->border[5].n = vec_xyz( 0.0, 0.0, 1.0 );
662
663 walls->border[4].mu = 0.2;
664 walls->border[4].loss0 = 0.6;
665 walls->border[4].loss_max = 0.9;
666 walls->border[4].loss_wspeed = 2.0;
667 walls->border[5].mu = 0.2;
668 walls->border[5].loss0 = 0.6;
669 walls->border[5].loss_max = 0.9;
670 walls->border[5].loss_wspeed = 2.0;
671
672 /* no holes */
673 walls->holenr = 0;
674 if( walls->hole != NULL ) billard_free( walls->hole );
675 walls->hole = billard_malloc(sizeof(HoleType)*walls->holenr);
676 }
677
678
create_8ball_scene(BallsType * balls)679 void create_8ball_scene( BallsType * balls )
680 {
681 int i;
682 myvec dball1, dball2, vdummy;
683 // double poserr=0.002;
684 double poserr=0.007;
685
686 balls->gametype=GAME_8BALL;
687 /* balls */
688 balls->nr=16;
689 if( balls->ball != NULL ) billard_free( balls->ball );
690 balls->ball = billard_malloc(sizeof(BallType)*balls->nr);
691
692 place8ballnrs(balls);
693
694 for(i=0;i<balls->nr;i++){
695 balls->ball[i].m=BALL_M;
696 /* I_kugel = (m.r^2)2/5 = (m.d^2)/10 */
697 balls->ball[i].I=BALL_M*BALL_D*BALL_D/10.0/**0.01*/;
698 balls->ball[i].d=BALL_D;
699 balls->ball[i].v=vec_xyz(0.0,0.0,0.0);
700 balls->ball[i].w=vec_xyz(0.0,0.0,0.0);
701 balls->ball[i].b[0]=vec_unit(vec_xyz(rand(),rand(),rand()));
702 vdummy=vec_xyz(rand(),rand(),rand());
703 balls->ball[i].b[1]=vec_unit(vec_diff(vdummy,vec_proj(vdummy,balls->ball[i].b[0])));
704 balls->ball[i].b[2]=vec_cross(balls->ball[i].b[0],balls->ball[i].b[1]);
705 balls->ball[i].in_game=1;
706 balls->ball[i].in_hole=0;
707 }
708
709 dball1=vec_scale( vec_xyz(-0.5, 0.5*sqrt(3.0), 0.0), (1.0+2.0*poserr)*BALL_D );
710 dball2=vec_scale( vec_xyz( 1.0, 0.0, 0.0), (1.0+2.0*poserr)*BALL_D );
711 /* white ball */
712 balls->ball[0].r = vec_xyz(0.0,-TABLE_L/4.0,0.0);
713 // balls->ball[0].w = vec_xyz(-M_PI*5.0,0.0,-M_PI*5.0);
714 balls->ball[0].w = vec_xyz(0.0,0.0,0.0);
715 /* other balls */
716 balls->ball[ 1].r = vec_xyz(0.0,TABLE_L/4.0,0.0);
717 balls->ball[ 2].r = vec_add( balls->ball[ 1].r, dball1 );
718 balls->ball[ 3].r = vec_add( balls->ball[ 2].r, dball2 );
719 balls->ball[ 4].r = vec_add( balls->ball[ 2].r, dball1 );
720 balls->ball[ 5].r = vec_add( balls->ball[ 4].r, dball2 );
721 balls->ball[ 6].r = vec_add( balls->ball[ 5].r, dball2 );
722 balls->ball[ 7].r = vec_add( balls->ball[ 4].r, dball1 );
723 balls->ball[ 8].r = vec_add( balls->ball[ 7].r, dball2 );
724 balls->ball[ 9].r = vec_add( balls->ball[ 8].r, dball2 );
725 balls->ball[10].r = vec_add( balls->ball[ 9].r, dball2 );
726 balls->ball[11].r = vec_add( balls->ball[ 7].r, dball1 );
727 balls->ball[12].r = vec_add( balls->ball[11].r, dball2 );
728 balls->ball[13].r = vec_add( balls->ball[12].r, dball2 );
729 balls->ball[14].r = vec_add( balls->ball[13].r, dball2 );
730 balls->ball[15].r = vec_add( balls->ball[14].r, dball2 );
731 // balls->ball[15].r = vec_xyz( 0, -TABLE_L/4, 0 );
732
733 /* add randomness to init positions */
734 for( i=1 ; i<balls->nr ; i++ ){
735 double ang, ampl;
736 myvec verr;
737 ang = (double)rand()/(double)RAND_MAX*2.0*M_PI;
738 DPRINTF("ball_placemet_err: angle=%f ",ang);
739 ampl = (double)rand()/(double)RAND_MAX*(poserr*0.95)*BALL_D;
740 DPRINTF("amplitude=%f\n",ampl);
741 verr = vec_scale( vec_xyz(cos(ang),sin(ang),0.0), (poserr*0.95)*BALL_D );
742 balls->ball[i].r = vec_add( balls->ball[i].r, verr );
743 }
744 for( i=1 ; i<balls->nr ; i++ ){
745 int j;
746 for( j=i+1 ; j<balls->nr ; j++ ){
747 if (vec_abs(vec_diff(balls->ball[i].r,balls->ball[j].r))/BALL_D<1.5){
748 DPRINTF("BALLLDISR(%d,%d)=%f\n",balls->ball[i].nr,balls->ball[j].nr,vec_abs(vec_diff(balls->ball[i].r,balls->ball[j].r))/BALL_D);
749 }
750 }
751 }
752
753 for( i=0 ; i<balls->nr ; i++ ){
754 balls->ball[i].path=0;
755 balls->ball[i].pathcnt=0;
756 balls->ball[i].pathsize=0;
757 }
758
759 // balls->ball[0].v=vec_xyz(1.5,2.0,0.0);
760 balls->ball[0].v=vec_xyz(0.0,0.0,0.0);
761 }
762
place9ballnrs(BallsType * balls)763 void place9ballnrs( BallsType * balls )
764 {
765 int i;
766
767 for(i=0;i<balls->nr;i++){
768 balls->ball[i].nr=i;
769 }
770 }
771
772
create_9ball_scene(BallsType * balls)773 void create_9ball_scene( BallsType * balls )
774 {
775 int i;
776 myvec dball1, dball2, vdummy;
777
778 balls->gametype=GAME_9BALL;
779 /* balls */
780 balls->nr=10;
781 if( balls->ball != NULL ) billard_free( balls->ball );
782 balls->ball = billard_malloc(sizeof(BallType)*balls->nr);
783
784 place9ballnrs(balls);
785
786 for(i=0;i<balls->nr;i++){
787 balls->ball[i].m=BALL_M;
788 /* I_kugel = (m.r^2)2/5 = (m.d^2)/10 */
789 balls->ball[i].I=BALL_M*BALL_D*BALL_D/10.0/**0.01*/;
790 balls->ball[i].d=BALL_D;
791 balls->ball[i].v=vec_xyz(0.0,0.0,0.0);
792 balls->ball[i].w=vec_xyz(0.0,0.0,0.0);
793 balls->ball[i].b[0]=vec_unit(vec_xyz(rand(),rand(),rand()));
794 vdummy=vec_xyz(rand(),rand(),rand());
795 balls->ball[i].b[1]=vec_unit(vec_diff(vdummy,vec_proj(vdummy,balls->ball[i].b[0])));
796 balls->ball[i].b[2]=vec_cross(balls->ball[i].b[0],balls->ball[i].b[1]);
797 balls->ball[i].in_game=1;
798 balls->ball[i].in_hole=0;
799 }
800
801 dball1=vec_scale(vec_xyz(-0.5*1.01, 0.5*sqrt(3.0)*1.01,0.0),BALL_D);
802 dball2=vec_scale(vec_xyz(+0.5*1.01, 0.5*sqrt(3.0)*1.01,0.0),BALL_D);
803 /* white ball */
804 balls->ball[0].r = vec_xyz(0.0,-TABLE_L/4.0,0.0);
805 // balls->ball[0].w = vec_xyz(-M_PI*5.0,0.0,-M_PI*5.0);
806 balls->ball[0].w = vec_xyz(0.0,0.0,0.0);
807 /* other balls */
808 balls->ball[ 1].r = vec_xyz(0.0,TABLE_L/4.0,0.0);
809 balls->ball[ 2].r = vec_add( balls->ball[1].r, vec_scale(dball2,2.0) );
810 balls->ball[ 3].r = vec_add( balls->ball[2].r, vec_scale(dball1,2.0) );
811 balls->ball[ 4].r = vec_add( balls->ball[1].r, vec_scale(dball1,2.0) );
812 balls->ball[ 5].r = vec_add( balls->ball[1].r, dball1 );
813 balls->ball[ 6].r = vec_add( balls->ball[1].r, dball2 );
814 balls->ball[ 7].r = vec_add( balls->ball[2].r, dball1 );
815 balls->ball[ 8].r = vec_add( balls->ball[4].r, dball2 );
816 balls->ball[ 9].r = vec_add( balls->ball[1].r, vec_add(dball1,dball2) );
817
818 /* add randomness to init positions */
819 for( i=1 ; i<balls->nr ; i++ ){
820 double ang, ampl;
821 myvec verr;
822 ang = rand();
823 ang = (double)rand()/(double)RAND_MAX*2.0*M_PI;
824 ampl = (double)rand()/(double)RAND_MAX*0.0049*BALL_D;
825 verr = vec_scale( vec_xyz(cos(ang),sin(ang),0.0), ampl );
826 balls->ball[i].r = vec_add( balls->ball[i].r, verr );
827 }
828
829 for( i=0 ; i<balls->nr ; i++ ){
830 balls->ball[i].path=0;
831 balls->ball[i].pathcnt=0;
832 balls->ball[i].pathsize=0;
833 }
834 // balls->ball[0].v=vec_xyz(1.5,2.0,0.0);
835 balls->ball[0].v=vec_xyz(0.0,0.0,0.0);
836 }
837
838
placecarambolballnrs(BallsType * balls)839 void placecarambolballnrs( BallsType * balls )
840 {
841 int i;
842
843 for(i=0;i<balls->nr;i++){
844 balls->ball[i].nr=i;
845 }
846 }
847
848
create_carambol_scene(BallsType * balls)849 void create_carambol_scene( BallsType * balls )
850 {
851 int i;
852 myvec vdummy;
853
854 balls->gametype=GAME_CARAMBOL;
855 /* balls */
856 balls->nr=3;
857 if( balls->ball != NULL ) billard_free( balls->ball );
858 balls->ball = billard_malloc(sizeof(BallType)*balls->nr);
859
860 placecarambolballnrs(balls);
861
862 for(i=0;i<balls->nr;i++){
863 balls->ball[i].nr=i;
864 }
865
866 for(i=0;i<balls->nr;i++){
867 balls->ball[i].m=BALL_M;
868 /* I_kugel = (m.r^2)2/5 = (m.d^2)/10 */
869 balls->ball[i].I=BALL_M*BALL_D*BALL_D/10.0/**0.01*/;
870 balls->ball[i].d=BALL_D;
871 balls->ball[i].v=vec_xyz(0.0,0.0,0.0);
872 balls->ball[i].w=vec_xyz(0.0,0.0,0.0);
873 balls->ball[i].b[0]=vec_unit(vec_xyz(rand(),rand(),rand()));
874 vdummy=vec_xyz(rand(),rand(),rand());
875 balls->ball[i].b[1]=vec_unit(vec_diff(vdummy,vec_proj(vdummy,balls->ball[i].b[0])));
876 balls->ball[i].b[2]=vec_cross(balls->ball[i].b[0],balls->ball[i].b[1]);
877 balls->ball[i].in_game=1;
878 balls->ball[i].in_hole=0;
879 }
880
881 /* white ball */
882 balls->ball[0].r = vec_xyz( TABLE_W/4.0, -TABLE_L/4.0, 0.0 );
883 balls->ball[1].r = vec_xyz( 0.0, -TABLE_L/4.0, 0.0 );
884 balls->ball[2].r = vec_xyz( 0.0, +TABLE_L/4.0, 0.0 );
885
886 for( i=0 ; i<balls->nr ; i++ ){
887 balls->ball[i].path=0;
888 balls->ball[i].pathcnt=0;
889 balls->ball[i].pathsize=0;
890 }
891 }
892
893
placesnookerballnrs(BallsType * balls)894 void placesnookerballnrs( BallsType * balls )
895 {
896 int i;
897
898 /* for(i=0;i<8;i++){
899 balls->ball[i].nr=i;
900 }*/
901 for(i=0;i<balls->nr;i++){
902 balls->ball[i].nr=i;
903 }
904 }
905
try_snooker_spot(BallsType * balls,struct Vect spot)906 int try_snooker_spot(BallsType *balls,struct Vect spot)
907 {
908 int i,available=1;
909 for(i=0;i<22;i++)
910 {
911 if(balls->ball[i].in_game && vec_abs(vec_diff(spot,balls->ball[i].r)) < (balls->ball[i].d) + 0.001)
912 {
913 available=0;
914 }
915 }
916 return available;
917 }
918
919 #define TABLE_SCALE (TABLE_L/(3.571042))
spot_snooker_ball(BallsType * balls,int nr)920 void spot_snooker_ball(BallsType *balls,int nr)
921 {
922
923 int i,found=0;
924 struct Vect spots[8];
925 spots[0]=vec_xyz(0.1,-TABLE_L/2+TABLE_SCALE*0.737,0.0);/*white*/
926 spots[2]=vec_xyz(TABLE_SCALE*0.292,-TABLE_L/2+TABLE_SCALE*0.737,0.0);/*yellow*/
927 spots[3]=vec_xyz(-TABLE_SCALE*0.292,-TABLE_L/2+TABLE_SCALE*0.737,0.0);/*green*/
928 spots[4]=vec_xyz(0.0,-TABLE_L/2+TABLE_SCALE*0.737,0.0);/*brown*/
929 spots[5]=vec_xyz(0.0,0.0,0.0);/*blue*/
930 spots[6]=vec_xyz(0.0,TABLE_L/4.0,0.0);/*pink*/
931 spots[7]=vec_xyz(0.0,TABLE_L/2-TABLE_SCALE*0.324,0.0);/*black*/
932
933 balls->ball[nr].in_game=0;
934
935 if(try_snooker_spot(balls,spots[nr]))
936 {
937 balls->ball[nr].r=spots[nr];
938 found=1;
939 }
940 else
941 {
942 i=7;
943 while(i>=2 && !found)
944 {
945 if(try_snooker_spot(balls,spots[i]))
946 {
947 balls->ball[nr].r=spots[i];
948 found=1;
949 }
950 i--;
951 }
952 }
953 if(!found)
954 {
955 struct Vect try=spots[nr];
956 while(!try_snooker_spot(balls,try))
957 {
958 try.y-=0.001;
959 }
960 balls->ball[nr].r=try;
961 }
962 balls->ball[nr].in_game=1;
963 balls->ball[nr].in_hole=0;
964 balls->ball[nr].v=vec_xyz(0.0,0.0,0.0);
965 balls->ball[nr].w=vec_xyz(0.0,0.0,0.0);
966 }
967
create_snooker_scene(BallsType * balls)968 void create_snooker_scene( BallsType * balls )
969 {
970 int i;
971 myvec dball1, dball2, vdummy;
972
973 balls->gametype=GAME_SNOOKER;
974 /* balls */
975 balls->nr=22;
976 if( balls->ball != NULL ) billard_free( balls->ball );
977 balls->ball = billard_malloc(sizeof(BallType)*balls->nr);
978
979 placesnookerballnrs(balls);
980
981 for(i=0;i<balls->nr;i++){
982 balls->ball[i].m=BALL_M;
983 /* I_kugel = (m.r^2)2/5 = (m.d^2)/10 */
984 balls->ball[i].I=BALL_M*BALL_D*BALL_D/10.0/**0.01*/;
985 balls->ball[i].d=BALL_D;
986 balls->ball[i].r = vec_xyz(TABLE_L*3,TABLE_L*3,0.0); /* get balls out of the way */
987 balls->ball[i].v=vec_xyz(0.0,0.0,0.0);
988 balls->ball[i].w=vec_xyz(0.0,0.0,0.0);
989 balls->ball[i].b[0]=vec_unit(vec_xyz(rand(),rand(),rand()));
990 vdummy=vec_xyz(rand(),rand(),rand());
991 balls->ball[i].b[1]=vec_unit(vec_diff(vdummy,vec_proj(vdummy,balls->ball[i].b[0])));
992 balls->ball[i].b[2]=vec_cross(balls->ball[i].b[0],balls->ball[i].b[1]);
993 balls->ball[i].in_game=1;
994 balls->ball[i].in_hole=0;
995 }
996
997 dball1=vec_scale(vec_xyz(-0.5*1.01, 0.5*sqrt(3.0)*1.01,0.0),BALL_D);
998 dball2=vec_scale(vec_xyz( 1.01, 0.0, 0.0),BALL_D);
999 /* red balls */
1000 balls->ball[ 1].r = vec_xyz(0.0,TABLE_L/4.0+1.1*BALL_D,0.0);
1001 balls->ball[ 8].r = vec_add( balls->ball[ 1].r, dball1 );
1002 balls->ball[ 9].r = vec_add( balls->ball[ 8].r, dball2 );
1003 balls->ball[10].r = vec_add( balls->ball[ 8].r, dball1 );
1004 balls->ball[11].r = vec_add( balls->ball[10].r, dball2 );
1005 balls->ball[12].r = vec_add( balls->ball[11].r, dball2 );
1006 balls->ball[13].r = vec_add( balls->ball[10].r, dball1 );
1007 balls->ball[14].r = vec_add( balls->ball[13].r, dball2 );
1008 balls->ball[15].r = vec_add( balls->ball[14].r, dball2 );
1009 balls->ball[16].r = vec_add( balls->ball[15].r, dball2 );
1010 balls->ball[17].r = vec_add( balls->ball[13].r, dball1 );
1011 balls->ball[18].r = vec_add( balls->ball[17].r, dball2 );
1012 balls->ball[19].r = vec_add( balls->ball[18].r, dball2 );
1013 balls->ball[20].r = vec_add( balls->ball[19].r, dball2 );
1014 balls->ball[21].r = vec_add( balls->ball[20].r, dball2 );
1015
1016 /* color balls */
1017 for(i=7;i>=2;i--)
1018 {
1019 spot_snooker_ball(balls,i);
1020 }
1021 /* white ball */
1022 spot_snooker_ball(balls,0);
1023
1024 /* add randomness to init positions */
1025 for( i=1 ; i<balls->nr ; i++ ){
1026 double ang, ampl;
1027 myvec verr;
1028 ang = (double)rand()/(double)RAND_MAX*2.0*M_PI;
1029 ampl = (double)rand()/(double)RAND_MAX*0.0049*BALL_D;
1030 verr = vec_scale( vec_xyz(cos(ang),sin(ang),0.0), ampl );
1031 balls->ball[i].r = vec_add( balls->ball[i].r, verr );
1032 }
1033
1034 for( i=0 ; i<balls->nr ; i++ ){
1035 balls->ball[i].path=0;
1036 balls->ball[i].pathcnt=0;
1037 balls->ball[i].pathsize=0;
1038 }
1039 // balls->ball[0].v=vec_xyz(1.5,2.0,0.0);
1040 balls->ball[0].v=vec_xyz(0.0,0.0,0.0);
1041 }
1042
1043
1044
balls_in_game(BallsType * balls,int full_half)1045 int balls_in_game( BallsType * balls, int full_half )
1046 /* without white, 8 is neither full nor half */
1047 {
1048 int i;
1049 int nr=0;
1050 for(i=1;i<balls->nr;i++) {
1051 if( ( ( full_half==BALL_FULL && balls->ball[i].nr<8 ) ||
1052 ( full_half==BALL_HALF && balls->ball[i].nr>8 ) ||
1053 ( full_half==BALL_ANY ) ) &&
1054 balls->ball[i].in_game
1055 ) nr++;
1056 }
1057 return nr;
1058 }
1059