FreeWRL/FreeX3D  3.0.0
Collision.h
1 /*
2 
3 
4 Collision ???
5 
6 */
7 
8 /****************************************************************************
9  This file is part of the FreeWRL/FreeX3D Distribution.
10 
11  Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
12 
13  FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
14  it under the terms of the GNU Lesser Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  FreeWRL/FreeX3D is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  GNU General Public License for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
25 ****************************************************************************/
26 
27 
28 #ifndef __FREEWRL_COLLISION_H__
29 #define __FREEWRL_COLLISION_H__
30 
31 #ifdef HAVE_OPENCL
32 // OLD_IPHONE_AQUA #if defined (__APPLE__) || defined(MACOSX) || defined(TARGET_AQUA)
33 // OLD_IPHONE_AQUA #include <OpenCL/opencl.h>
34 // OLD_IPHONE_AQUA #include <OpenGL/CGLDevice.h>
35 // OLD_IPHONE_AQUA #elif defined(_MSC_VER)
36 
37 
38 #if defined(_MSC_VER)
39  #include <windows.h> //WGL prototyped in wingdi.h
40  #include <CL/opencl.h>
41  #define DEBUG
42 #else //LINUX
43  #include <CL/opencl.h>
44 #endif
45 #endif // HAVE_OPENCL
46 
47 
48 
49 /* Collision detection results structure*/
51  struct point_XYZ Offset;
52  int Count;
53  double Maximum2; /*squared. so we only need to root once */
54 };
55 
56 typedef int prflags;
57 #define PR_DOUBLESIDED 0x01
58 #define PR_FRONTFACING 0x02 /* overrides effect of doublesided. */
59 #define PR_BACKFACING 0x04 /* overrides effect of doublesided, all normals are reversed. */
60 #define PR_NOSTEPING 0x08 /* gnores stepping. used internally */
61 
62 
63 /*uncomment this to enable the scene exporting functions */
64 /*#define DEBUG_SCENE_EXPORT*/
65 
66 struct point_XYZ
67 polyrep_disp_rec(double y1,
68  double y2,
69  double ystep,
70  double r,
71  struct X3D_PolyRep* pr,
72  struct point_XYZ* n,
73  struct point_XYZ dispsum,
74  prflags flags);
75 
76 /*accumulator function, for displacements. */
77 void accumulate_disp(struct sCollisionInfo* ci, struct point_XYZ add);
78 
79 /*feed a box (a corner, and the three vertice sides) and the stats of a cylinder, it returns the
80  displacement of the box that is needed for them not to intersect any more, with optionnal stepping displacement */
81 struct point_XYZ box_disp(double y1, double y2, double ystep, double r,struct point_XYZ p0, struct point_XYZ i, struct point_XYZ j, struct point_XYZ k);
82 
83 /*fast test to see if a box intersects a y-cylinder.
84  * gives false positives */
85 int fast_ycylinder_box_intersect(double y1, double y2, double r,struct point_XYZ pcenter, double xs, double ys, double zs);
86 
87 
88 /*fast test to see if a cone intersects a y-cylinder. */
89 /*gives false positives. */
90 int fast_ycylinder_cone_intersect(double y1, double y2, double r,struct point_XYZ pcenter, double halfheight, double baseradius);
91 
92 /*algorithm is approximative */
93 /*basically, it does collision with a triangle on a plane that passes through the origin.*/
94 struct point_XYZ cone_disp(double y1, double y2, double ydisp, double r, struct point_XYZ base, struct point_XYZ top, double baseradius);
95 
96 /*algorithm is approximative */
97 /*basically, it does collision with a rectangle on a plane that passes through the origin.*/
98 struct point_XYZ cylinder_disp(double y1, double y2, double ydisp, double r, struct point_XYZ base, struct point_XYZ top, double baseradius);
99 
100 struct point_XYZ polyrep_disp2(struct X3D_PolyRep pr, GLDOUBLE* mat, prflags flags);
101 
102 /*displacement when the polyrep structure is all in the same plane
103  if normal is zero, it will be calculated form the first triangle*/
104 struct point_XYZ planar_polyrep_disp(double y1, double y2, double ydisp, double r, struct X3D_PolyRep pr, GLDOUBLE* mat, prflags flags, struct point_XYZ n);
105 
106 // struct point_XYZ elevationgrid_disp( double y1, double y2, double ydisp, double r, struct X3D_PolyRep pr, int xdim, int zdim, double xs, double zs, GLDOUBLE* mat, prflags flags);
107 
108 /* functions VERY usefull for debugging purposes
109  Use these inside FreeWRL to export a scene to
110  the debugging programs. */
111 #ifdef DEBUG_SCENE_EXPORT
112 void printpolyrep(struct X3D_PolyRep pr, int npoints);
113 
114 void printmatrix(GLDOUBLE* mat);
115 #endif
116 
117 
118 #ifdef HAVE_OPENCL
119 // GPU Collision info
120 struct sCollisionGPU {
121  cl_program CollideGPU_program;
122  cl_kernel CollideGPU_kernel;
123  size_t CollideGPU_workgroup_size;
124  int CollideGPU_output_size;
125  cl_mem CollideGPU_output_buffer;
126  cl_mem CollideGPU_matrix_buffer;
127  cl_mem CollideGPU_vertex_buffer;
128  cl_mem CollideGPU_index_buffer;
129  struct Multi_ColorRGBA CollideGPU_returnValues;
130 };
131 #endif
132 
133 
134 
135 #define VIEWER_WALK 2
136 //int viewer_type = VIEWER_WALK; // force to walking
137 struct sFallInfo
138 {
139  double fallHeight; /*[100.0] a setting - the maximum you want to search for ground beneath before giving up and staying at your current level */
140  double fallStep; /*[1.0] a setting - how much maximum on a frame to fall ie so it's not 1 frame to fall all the way, you can spread it out */
141  double hfall; /*if canFall && isFall then this is how far to fall to hit ground, in collision space dist +down */
142  double hclimb; /* if isClimb then (similar to hfall) this is how far to climb to get back on top of the ground - redundant with cylinder collisions, so this is a primitive thunk */
143  int isFall; /* true if there's ground underneath (within fallHeight) to fall to, and no climb is registered (isClimb is false) */
144  int canFall; /* true if WALKING && COLLISION, set in render_pre() */
145  int isClimb; /* true if avatar feet are below ground, in which case add hclimb in collision space */
146  int hits; /* counter of vertical intersections found per frame*/
147  int walking; /* true if viewer_type == VIEWER_WALK, initialize before doing collision detection */
148  int smoothStep; /* [1] setting - will only fall by fallstep on a frame rather than the full hfall */
149 
150  int allowClimbing; /* [0] - setting - will allow climbing in which case cyclindrical Y collision is over-ridden */
151  /* the following could be moved to sCollisionInfo */
152  GLDOUBLE collision2avatar[16], avatar2collision[16]; /* fly/examine: Identity, walk: BVVA2A, A2BVVA (BVVA bound-viewpoint-vertical avatar-centric) see viewer.c */
153 
154  int checkFall;
155  int checkCylinder;
156  int checkPenetration;
157 
158  int canPenetrate; /* setting 1 will check for wall penetration */
159  int isPenetrate; /* initialize to 0 once per frame, will return as 1 if a wall penetration was found */
160  GLDOUBLE penMin[3], penMax[3]; /* MBB of scaled penetration vector (penRadius x penvec) - initialize once per frame */
161  struct point_XYZ penvec; /* normalized (unit) vector from avatar(0,0,0) to last valid avatar position ie on last frame/loop */
162  double penRadius; /* distance from avatar(0,0,0) to last avatar position */
163  struct point_XYZ pencorrection; /* if isPenetration, this will hold the displacement vector to apply to the avatar position to un penetrate */
164  double pendisp; /* set to zero once per frame, used to sort (pick) penetration intersection closest to last position */
165 };
166 
167 int fast_ycylinder_box_intersect(double y1, double y2, double r,struct point_XYZ pcenter, double xs, double ys, double zs);
168 int fast_sphere_MBB_intersect_shapeSpace(double r, GLDOUBLE *collision2shape, GLDOUBLE *shapeMBBmin, GLDOUBLE *shapeMBBmax );
169 int fast_ycylinder_MBB_intersect_shapeSpace(double y1, double y2, double r, GLDOUBLE *collision2shape, GLDOUBLE *shapeMBBmin, GLDOUBLE *shapeMBBmax );
170 int fast_ycylinder_MBB_intersect_collisionSpace(double y1, double y2, double r, GLDOUBLE *shape2collision, GLDOUBLE *shapeMBBmin, GLDOUBLE *shapeMBBmax );
171 int fast_sphere_MBB_intersect_collisionSpace(double r, GLDOUBLE *shape2collision, GLDOUBLE *shapeMBBmin, GLDOUBLE *shapeMBBmax );
172 int overlapMBBs(GLDOUBLE *MBBmin1, GLDOUBLE *MBBmax1, GLDOUBLE *MBBmin2, GLDOUBLE* MBBmax2);
173 int fast_ycylinder_polyrep_intersect2(double y1, double y2, double AVr,struct point_XYZ pcenter, double scale, double *minVals, double *maxVals);
174 
175 #ifdef HAVE_OPENCL
176 struct sCollisionGPU* GPUCollisionInfo();
177 struct point_XYZ run_non_walk_collide_program(GLuint vertex_vbo, GLuint index_vbo, float *modelMat,int ntri,
178  int face_ccw, int face_flags, float avatar_radius);
179 bool collision_initGPUCollide (struct sCollisionGPU*);
180 void createGPUCollisionProgram();
181 #endif
182 
183 
184 #endif /* __FREEWRL_COLLISION_H__ */