Project

General

Profile

Statistics
| Revision:

root / branches / simulator / projects / simulator / simulator / core / world.c @ 1041

History | View | Annotate | Download (5.78 KB)

1 1022 bpoole
/**
2
 * @file world.c
3
 * @author Colony Project
4
 * @brief Simulator world code
5
 *
6
 * This is the world.
7
 **/
8
9
#include <stdio.h>
10 1026 bpoole
#include <stdlib.h>
11
#include <math.h>
12
#include <stdarg.h>
13 1022 bpoole
#include "world.h"
14
15 1040 bpoole
world_t world;
16 1022 bpoole
17 1040 bpoole
int init_world(int max_objs, bbox_t b)
18
{
19
    world.max_objs = max_objs;
20
    world.cur_objs = 0;
21
    world.objs = calloc(max_objs,  sizeof(object_t));
22
    world.win = b;
23
    //PBBOX(b);
24
}
25
int destroy_world()
26
{
27
    int i;
28
    for (i = 0; i < world.cur_objs; i++) {
29
        destroy(&world.objs[i]);
30
    }
31
    free(world.objs);
32
}
33 1026 bpoole
34
double (*collide_func[NUM_SHAPES])(ray_t *ray, object_t *obj) =
35
    {
36
    collide_poly
37
    };
38
int (*create_func[NUM_SHAPES])(object_t *obj, va_list ap) =
39
{
40
    create_poly
41
};
42 1040 bpoole
int (*destroy_func[NUM_SHAPES])(object_t *obj) =
43
    {
44
    destroy_poly
45
    };
46
47
48
49 1026 bpoole
double collide_circle(ray_t *ray, object_t *obj)
50
{
51 1022 bpoole
    return -1;
52
}
53 1026 bpoole
54
double collide_seg(ray_t *ray, point_t p3, point_t p4)
55
{
56
    double denom, nume_a, nume_b, ua, ub, xint, yint, dist;
57
    point_t p1 = ray->p;
58
    point_t p2 = {ray->p.x+cos(ray->d),ray->p.y+sin(ray->d)};
59
60
   // printf("(%g,%g) --> (%g,%g) with (%g,%g) --> (%g,%g)\n",p1.x,p1.y,p2.x,p2.y,p3.x,p3.y,p4.x,p4.y);
61
    denom = (p2.y-p1.y)*(p4.x-p3.x)-(p2.x-p1.x)*(p4.y-p3.y);
62
    if (denom == 0) {
63
        return RAY_MISS;
64
    }
65
    nume_a = (p2.x-p1.x)*(p3.y-p1.y)-(p2.y-p1.y)*(p3.x-p1.x);
66
    nume_b = (p4.x-p3.x)*(p3.y-p1.y)-(p4.y-p3.y)*(p3.x-p1.x);
67
68
    ua = nume_a/denom;
69
    if (ua < 0 || ua > 1) {
70
        return RAY_MISS;
71
    }
72
73
    ub = nume_b/denom;
74
    if (ub < 0) {
75
        return RAY_MISS;
76
    }
77
78
    xint = p3.x+ua*(p4.x-p3.x);
79
    yint = p3.y+ua*(p4.y-p3.y);
80
    dist = sqrt((xint-p1.x)*(xint-p1.x)+(yint-p1.y)*(yint-p1.y));
81
    return dist;
82
83 1022 bpoole
}
84
85 1026 bpoole
double collide_poly(ray_t *ray, object_t *obj)
86
{
87
    int i;
88
    double min = RAY_MISS;
89
    double x;
90
    poly_t *p = (poly_t *) obj->props;
91
92
    if (obj->id != ID_POLY){
93
        return -1;
94
    }
95
96
    for (i = 0; i < p->num_pts - 1; i++) {
97
        if ((x = collide_seg(ray, p->pts[i], p->pts[i+1])) < min){
98
            min = x;
99
        }
100
    }
101 1040 bpoole
    if (p->type == POLY_CONNECTED) {
102 1026 bpoole
        if ((x = collide_seg(ray,p->pts[i],p->pts[0])) < min)
103
            min = x;
104
    }
105
    return min;
106
}
107
108
double collide(ray_t *ray, object_t *obj)
109
{
110 1022 bpoole
    if (ray == NULL || obj == NULL)
111 1026 bpoole
    {
112 1022 bpoole
        return -1;
113 1026 bpoole
    }
114 1040 bpoole
    return collide_func[obj->id+ID_OFFSET](ray, obj);
115 1022 bpoole
}
116 1026 bpoole
117
118
119
object_t *create(int id, ...)
120
{
121 1040 bpoole
    object_t *obj = &(world.objs[world.cur_objs++]);
122 1026 bpoole
    va_list args;
123
124
    va_start(args, id);
125 1040 bpoole
    if (create_func[id+ID_OFFSET](obj, args) < 0) {
126
        /* Cleanup ? */
127 1026 bpoole
    }
128
    va_end(args);
129
    return obj;
130
}
131
132 1040 bpoole
int destroy(object_t *obj)
133
{
134
    if (obj->id == ID_NULL)
135
        return 0;
136
    destroy_func[obj->id+ID_OFFSET](obj);
137
    obj->id = ID_NULL;
138
}
139
140 1026 bpoole
/**
141
 *
142
 **/
143
int create_poly(object_t *obj, va_list ap)
144
{
145
    int i;
146
    poly_t *p;
147
148
    int argc =  va_arg(ap, int);
149
    int poly_type = va_arg(ap, int);
150
151
    p = malloc(sizeof(poly_t));
152
153
154
    p->num_pts = argc;
155
    p->pts = malloc((argc) * sizeof(point_t));
156
    p->type = poly_type;
157
158 1041 chihsiuh
    double* pts = (double*) malloc((argc) * sizeof(double) * 2);
159
    pts = va_arg(ap,double*);
160
161 1026 bpoole
    for(i=0;i < argc; i++) {
162 1041 chihsiuh
        p->pts[i].x = pts[2*i];
163
        p->pts[i].y = pts[2*i+1];
164 1026 bpoole
    }
165
    obj->id = ID_POLY;
166
    obj->bbox = NULL;
167
    obj->props = p;
168
    return 1;
169
}
170
171
int create_rect(object_t *obj, va_list ap)
172
{
173
    int i;
174
    poly_t *p;
175
    int argc = va_arg(ap, int);
176
}
177
178 1040 bpoole
int destroy_poly (object_t *obj)
179 1026 bpoole
{
180
    poly_t *p;
181
    p =  (poly_t *)obj->props;
182
    if (p != NULL) free(p->pts);
183
    free(p);
184 1040 bpoole
    return 1;
185
}
186 1026 bpoole
187 1040 bpoole
void print_world(void)
188
{
189
    int i;
190
    printf("WORLD: %d object(s) in (%g,%g)->(%g,%g)\n", world.cur_objs, world.win.p1.x,world.win.p1.y,world.win.p2.x,world.win.p2.y);
191
    for (i = 0; i < world.cur_objs; i++) {
192
        print_object(&world.objs[i]);
193 1026 bpoole
    }
194
}
195
void print_object(object_t *obj)
196
{
197
    int i;
198
    poly_t *p;
199
    switch (obj->id) {
200 1040 bpoole
        case ID_NULL:
201
            printf("\tNULL\n");
202 1026 bpoole
        case ID_POLY:
203
            p = (poly_t *) obj->props;
204 1040 bpoole
            printf("\tPOLYGON (%d points, %s) { ", p->num_pts, p->type?"connected" : "disconnected");
205 1026 bpoole
            for (i = 0; i < p->num_pts; i++){
206
                printf("(%g, %g) ", p->pts[i].x, p->pts[i].y);
207
            }
208
            printf("}\n");
209
            break;
210
        default:
211
            break;
212
213
    }
214
}
215
216 1041 chihsiuh
int starts_with (const char* line, const char* word) {
217
  do {
218
    line++;
219
    word++;
220
  }while (*line == *word);
221
  if (*word == '\n' || *word == '\0') return 0;
222
  return 1;
223
}
224 1026 bpoole
225 1041 chihsiuh
int load_object (const char* line) {
226
  char buf[BUF_SIZE];
227
  int i = 0;
228
  int j;
229
  int id;
230
  if (starts_with(line,"POLYGON") == 0){
231
    int num;
232
    int type;
233
    double *pts;
234
    id = ID_POLY;
235
    i = strlen("POLYGON")+1;
236
237
    sscanf(line+i,"%s",buf);
238
    num = strtol(buf,NULL,0);
239
    i += strlen(buf) + 1;
240
241
    if (starts_with(line+i,"CONNECTED") == 0){
242
      i += strlen("CONNECTED") + 1;
243
      type = POLY_CONNECTED;
244
    }else if (starts_with(line+i,"DISCONNECTED") == 0){
245
      i += strlen("DISCONNECTED") + 1;
246
      type = POLY_DISCONNECTED;
247
    }else if (starts_with(line+i,"RECT") == 0){
248
      i += strlen("RECT") + 1;
249
      type = POLY_RECT;
250
    }else{
251
      // invalid input
252
        fprintf(stderr,"Invalid input for POLYGON\n");
253
      return -1;
254
    }
255
256
    char *c1,*c2;
257
    c1 = (char*)(line+i);
258
    c2 = (char*)(line+i);
259
    pts = (double*) malloc(sizeof(double)*num*2);
260
    for (j = 0;j < num;j++){
261
      pts[2*j] = strtod(c1,&c2);
262
      pts[2*j+1] = strtod(c2,&c1);
263
      printf("%lf %lf\n",pts[2*j],pts[2*j+1]);
264
    }
265
266
    create(id,num,type,pts);
267
    free(pts);
268
  }
269
  return 0;
270
}
271
272
int load_world (const char* filename) {
273
  FILE* fin;
274
  char buf[BUF_SIZE];
275
  bbox_t bbox = {0,0,0,0};
276
  if ((fin = fopen(filename,"r"))==NULL){
277
    // open file failed
278
        perror("Fail to open file");
279
    return -1;
280
  }
281
  if (fgets(buf,512,fin) != NULL){
282
    sscanf(buf,"WORLD %lf %lf %lf %lf",&bbox.p1.x,&bbox.p1.y,&bbox.p2.x,&bbox.p2.y);
283
    init_world(MAX_OBJS, bbox);
284
    while (fgets(buf,512,fin) != NULL){
285
      load_object(buf);
286
    }
287
  }
288
  fclose(fin);
289
  return 0;
290
}