FreeWRL / FreeX3D 4.3.0
Collision.h
1/*
2
3
4Collision ???
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
56typedef 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
66struct point_XYZ
67polyrep_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. */
77void 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 */
81struct 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 */
85int 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. */
90int 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.*/
94struct 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.*/
98struct point_XYZ cylinder_disp(double y1, double y2, double ydisp, double r, struct point_XYZ base, struct point_XYZ top, double baseradius);
99
100struct 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*/
104struct 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
112void printpolyrep(struct X3D_PolyRep pr, int npoints);
113
114void printmatrix(GLDOUBLE* mat);
115#endif
116
117
118#ifdef HAVE_OPENCL
119// GPU Collision info
120struct 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
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 climbHeight; //100 the max you want to search above for ground above you
141 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 */
142 double hfall; /*if canFall && isFall then this is how far to fall to hit ground, in collision space dist +down */
143 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 */
144 int isFall; /* true if there's ground underneath (within fallHeight) to fall to, and no climb is registered (isClimb is false) */
145 int canFall; /* true if WALKING && COLLISION, set in render_pre() */
146 int isClimb; /* true if avatar feet are below ground, in which case add hclimb in collision space */
147 int hits; /* counter of vertical intersections found per frame*/
148 int walking; /* true if viewer_type == VIEWER_WALK, initialize before doing collision detection */
149 int smoothStep; /* [1] setting - will only fall by fallstep on a frame rather than the full hfall */
150
151 int allowClimbing; /* [0] - setting - will allow climbing in which case cyclindrical Y collision is over-ridden */
152 /* the following could be moved to sCollisionInfo */
153 GLDOUBLE collision2avatar[16], avatar2collision[16]; /* fly/examine: Identity, walk: BVVA2A, A2BVVA (BVVA bound-viewpoint-vertical avatar-centric) see viewer.c */
154
155 int checkFall;
156 int checkCylinder;
157 int checkPenetration;
158
159 int canPenetrate; /* setting 1 will check for wall penetration */
160 int isPenetrate; /* initialize to 0 once per frame, will return as 1 if a wall penetration was found */
161 GLDOUBLE penMin[3], penMax[3]; /* MBB of scaled penetration vector (penRadius x penvec) - initialize once per frame */
162 struct point_XYZ penvec; /* normalized (unit) vector from avatar(0,0,0) to last valid avatar position ie on last frame/loop */
163 double penRadius; /* distance from avatar(0,0,0) to last avatar position */
164 struct point_XYZ pencorrection; /* if isPenetration, this will hold the displacement vector to apply to the avatar position to un penetrate */
165 double pendisp; /* set to zero once per frame, used to sort (pick) penetration intersection closest to last position */
166};
167
168int fast_ycylinder_box_intersect(double y1, double y2, double r,struct point_XYZ pcenter, double xs, double ys, double zs);
169int fast_sphere_MBB_intersect_shapeSpace(double r, GLDOUBLE *collision2shape, GLDOUBLE *shapeMBBmin, GLDOUBLE *shapeMBBmax );
170int fast_ycylinder_MBB_intersect_shapeSpace(double y1, double y2, double r, GLDOUBLE *collision2shape, GLDOUBLE *shapeMBBmin, GLDOUBLE *shapeMBBmax );
171int fast_ycylinder_MBB_intersect_collisionSpace(double y1, double y2, double r, GLDOUBLE *shape2collision, GLDOUBLE *shapeMBBmin, GLDOUBLE *shapeMBBmax );
172int fast_sphere_MBB_intersect_collisionSpace(double r, GLDOUBLE *shape2collision, GLDOUBLE *shapeMBBmin, GLDOUBLE *shapeMBBmax );
173int overlapMBBs(GLDOUBLE *MBBmin1, GLDOUBLE *MBBmax1, GLDOUBLE *MBBmin2, GLDOUBLE* MBBmax2);
174int fast_ycylinder_polyrep_intersect2(double y1, double y2, double AVr,struct point_XYZ pcenter, double scale, double *minVals, double *maxVals);
175
176#ifdef HAVE_OPENCL
177struct sCollisionGPU* GPUCollisionInfo();
178struct point_XYZ run_non_walk_collide_program(GLuint vertex_vbo, GLuint index_vbo, float *modelMat,int ntri,
179 int face_ccw, int face_flags, float avatar_radius);
180bool collision_initGPUCollide (struct sCollisionGPU*);
181void createGPUCollisionProgram();
182#endif
183
184
185#endif /* __FREEWRL_COLLISION_H__ */