Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/chris/core/collision.cc @ 1966

Last change on this file since 1966 was 1966, checked in by chris, 20 years ago

orxonox/branches/chris: Basic sphere-sphere collision code implemented, still lacks traceing (line-sphere collision)

File size: 5.1 KB
Line 
1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
14   main-programmer: Christian Meyer
15   co-programmer: ...
16*/
17
18
19#include "collision.h"
20
21
22using namespace std;
23
24CollisionCluster::CollisionCluster (float rad = 1.0, Vector mid = Vector(0,0,0))
25{
26  root = (CC_Tree*) malloc( sizeof( CC_Tree));
27  root->n = 0;
28  root->data.ID = 0;
29  root->r = rad;
30  root->m = mid;
31}
32
33CollisionCluster::CollisionCluster (char* filename)
34{
35  FILE* stream;
36  char hbuffer[3];
37  stream = fopen (filename, "rb");
38  if( stream == NULL)
39  {
40    root = NULL;
41    return;
42  }
43  if( fread (hbuffer, sizeof( char), 2, stream) != 2)
44  {
45    root = NULL;
46    return;
47  }
48 
49  hbuffer[2] = 0;
50  if( strcmp (hbuffer, "CC"))
51  {
52    root = NULL;
53    return;
54  }
55 
56  root = load_CC_Tree (stream);
57  fclose (stream);
58}
59
60CollisionCluster::~CollisionCluster ()
61{
62  free_CC_Tree( root);
63}
64
65int CollisionCluster::store (char* filename)
66{
67  int r;
68  FILE* stream;
69  stream = fopen( filename, "wb");
70  if( stream == NULL) return -1;
71  r = save_CC_Tree (root, stream);
72  fclose (stream);
73  return r;
74}
75
76bool check_trace (const Placement& pa, const CollisionCluster& a, unsigned long* ahitflags, const Line& trace, Vector* impactpoint)
77{
78  return false;
79}
80
81bool check_collision (const Placement* pa, const CollisionCluster* a, unsigned long* ahitflags, const Placement* pb, const CollisionCluster* b, unsigned long* bhitflags)
82{
83  CC_Tree* ta, *tb;
84  if( (ta = a->root) == NULL) return false;
85  if( (tb = b->root) == NULL) return false;
86 
87  return cctree_iterate(pa, ta, ahitflags, pb, tb, bhitflags);
88}
89
90bool sphere_sphere_collision( Vector m1, float r1, Vector m2, float r2)
91{
92  if ((m1-m2).len() < r1+r2) return true;
93  return false;
94}
95
96bool trace_sphere_collision( Vector m, float r, Line& l, Vector* impactpoint)
97{
98  return false;
99}
100
101bool cctree_iterate(const Placement* pa, CC_Tree* ta, unsigned long* ahitflags, const Placement* pb, CC_Tree* tb, unsigned long* bhitflags)
102{
103  bool r = false;
104  int ia, ib;
105  Vector mra = pa->r + rotate_vector( ta->m, pa->w);
106  Vector mrb = pb->r + rotate_vector( tb->m, pb->w);
107  CC_Tree* use_a, *use_b;
108 
109  if( use_a == NULL || use_b == NULL) return false;
110 
111  if( sphere_sphere_collision( mra, ta->r, mrb, tb->r))
112  {
113    if( ta->n == 0 && tb->n == 0)
114    {
115      setflag( ahitflags, ta->data.ID);
116      setflag( bhitflags, tb->data.ID);
117      return true;
118    }
119    for( ia = 0; ia < ta->n || ta->n == 0; ia++)
120    {
121      if( ta->n == 0) use_a = ta;
122      else use_a = ta->data.b[ia];
123      for( ib = 0; ib < tb->n || ta->n == 0; ib++)
124      {
125        if( ta->n == 0) use_b = ta;
126        else use_b = ta->data.b[ib];
127       
128        r = r || cctree_iterate( pa, use_a, ahitflags, pb, use_b, bhitflags);
129       
130        if( tb->n == 0) break;
131      }
132      if( ta->n == 0) break;
133    }
134    return r;
135  }
136 
137  return false;
138}
139
140void setflag( unsigned long* flags, unsigned long ID)
141{
142  unsigned long f;
143  f = 1;
144  for( int i = 0; i < ID; i++)
145  {
146    f *= 2;
147  }
148  *flags = *flags | f;
149  return;
150}
151
152void free_CC_Tree( CC_Tree* tree)
153{
154  if (tree == NULL) return;
155  for (int i = 0; i < tree->n; i++)
156  {
157    free_CC_Tree( tree->data.b[i]);
158  }
159  free( tree);
160}
161
162CC_Tree* load_CC_Tree (FILE* stream)
163{
164  CC_Tree* tree = NULL;
165  CC_Tree** branches = NULL;
166  float buf[4];
167  unsigned long n;
168  unsigned long ID;
169 
170  // first load vector and radius
171  if (fread( buf, sizeof (float), 4, stream) != 4) return NULL;
172  // then the amount of subbranches
173  if (fread( &n, sizeof(unsigned long), 1, stream) != 1) return NULL;
174  // then ID or the subbranches
175  if ( n == 0)
176  {
177    if (fread( &ID, sizeof(unsigned long), 1, stream) != 1) return NULL;
178  }
179  else
180  {
181    branches = (CC_Tree**)malloc( sizeof(CC_Tree*) * n);
182    for( int i = 0; i < n; i++)
183    {
184      if ((branches[i] = load_CC_Tree (stream)) == NULL)
185      {
186        for( int j = 0; j < i; j++)
187        {
188          free_CC_Tree (branches[j]);
189          free (branches);
190          return NULL;
191        }
192      }
193    }
194  }
195 
196  // assemble
197  tree = (CC_Tree*) malloc (sizeof(CC_Tree));
198  tree->m.x = buf[0];
199  tree->m.y = buf[1];
200  tree->m.z = buf[2];
201  tree->r = buf[3];
202  tree->n = n;
203  if( n == 0) tree->data.ID = ID;
204  else tree->data.b = branches;
205 
206  // then return
207  return tree;
208}
209
210int save_CC_Tree (CC_Tree* tree, FILE* stream)
211{
212  float buf[4];
213 
214  buf[0] = tree->m.x;
215  buf[1] = tree->m.y;
216  buf[2] = tree->m.z;
217  buf[3] = tree->r;
218 
219  // first save vector and radius
220  if (fwrite( buf, sizeof (float), 4, stream) != 4) return -1;
221  // then the amount of subbranches
222  if (fwrite( &(tree->n), sizeof(unsigned long), 1, stream) != 1) return -1;
223  // then ID or the subbranches
224  if ( tree->n == 0)
225  {
226    if (fwrite( &(tree->data.ID), sizeof(unsigned long), 1, stream) != 1) return -1;
227  }
228  else
229  {
230    for( int i = 0; i < tree->n; i++)
231    {
232      if ( save_CC_Tree (tree->data.b[i], stream) == -1) return -1;
233    }
234  }
235   
236  // then return
237  return 0;
238}
Note: See TracBrowser for help on using the repository browser.