#include <math.h>#include "locmath.h"#include "collision.h"#include "vector.h"#include "mmgr.h"Go to the source code of this file.
Functions | |
| void | SetLength (VECTOR &v, float l) |
| bool | IsZeroVector (VECTOR &v) |
| VECTOR | Wedge (VECTOR v1, VECTOR v2) |
| float | IntersectRayPlane (VECTOR rOrigin, VECTOR rVector, VECTOR pOrigin, VECTOR pNormal) |
| float | IntersectRaySphere (VECTOR rO, VECTOR rV, VECTOR sO, float sR) |
| bool | CheckPointInTriangle (VECTOR point, VECTOR a, VECTOR b, VECTOR c) |
| VECTOR | ClosestPointOnLine (VECTOR &a, VECTOR &b, VECTOR &p) |
| VECTOR | ClosestPointOnPolygon (VECTOR a, VECTOR c, VECTOR b, VECTOR p) |
| bool | CheckPointInSphere (VECTOR point, VECTOR sO, float sR) |
| VECTOR | TangentPlaneNormalOfEllipsoid (VECTOR point, VECTOR eO, VECTOR eR) |
| int | ClassifyPoint (VECTOR point, VECTOR pO, VECTOR pN) |
| void | CheckForCollision (POLYGON *polygon, VECTOR *destination, CollisionPacket *colPackage) |
Variables | |
| int | numPolygons |
|
||||||||||||||||
|
Definition at line 242 of file collision.cpp. References CheckPointInTriangle(), ClassifyPoint(), ClosestPointOnPolygon(), DotProduct(), CollisionPacket::eRadius, FALSE, CollisionPacket::foundCollision, POLYGON::GetNormal(), GetUnitVector(), IntersectRayPlane(), IntersectRaySphere(), MagnitudeVector(), CollisionPacket::nearestDistance, CollisionPacket::nearestPolygonIntersectionPoint, CollisionPacket::nearestSphereIntersectionPoint, numPolygons, polygon, SetLength(), CollisionPacket::sourcePoint, TRUE, CollisionPacket::velocity, POLYGON::Vertex, VECTOR::x, VERTEX::x, VECTOR::y, VERTEX::y, VECTOR::z, and VERTEX::z. Referenced by DrawGLScene().
00243 {
00244 colPackage->foundCollision = FALSE;
00245
00246 // from package
00247 VECTOR eRadius = colPackage->eRadius;
00248 VECTOR source = colPackage->sourcePoint;
00249 VECTOR velocity = colPackage->velocity;
00250
00251 // keep a copy of this as it's needed a few times
00252 VECTOR normalizedVelocity = GetUnitVector(velocity);
00253
00254 // intersection data
00255 VECTOR sIPoint; // sphere intersection point
00256 VECTOR pIPoint; // plane intersection point
00257 VECTOR polyIPoint; // polygon intersection point
00258
00259 float distToPlaneIntersection;
00260 float distToSphereIntersection;
00261
00262 // loop through all the polygons of the world
00263 for(int i = 0; i < numPolygons; i++)
00264 {
00265
00266 // Get plane normal
00267 VECTOR pOrigin;
00268 pOrigin.x = polygon[i].Vertex[0].x; //Set plane origin
00269 pOrigin.y = polygon[i].Vertex[0].y;
00270 pOrigin.z = polygon[i].Vertex[0].z;
00271 VECTOR pNormal = polygon[i].GetNormal();
00272
00273 // Normalize plane normal
00274 pNormal = GetUnitVector(pNormal);
00275
00276 if (DotProduct(pNormal, normalizedVelocity) <= 1.0f)
00277 {
00278 // Calculate sphere intersection point
00279 VECTOR eIPoint;
00280 eIPoint.x = source.x - pNormal.x; //Source point + inverted plane normal
00281 eIPoint.y = source.y - pNormal.y;
00282 eIPoint.z = source.z - pNormal.z;
00283
00284 // shoot ray along the velocity vector
00285 distToPlaneIntersection = IntersectRayPlane(eIPoint, normalizedVelocity, pOrigin, pNormal);
00286
00287 // calculate plane intersection point
00288 pIPoint.x = eIPoint.x + distToPlaneIntersection * normalizedVelocity.x;
00289 pIPoint.y = eIPoint.y + distToPlaneIntersection * normalizedVelocity.y;
00290 pIPoint.z = eIPoint.z + distToPlaneIntersection * normalizedVelocity.z;
00291
00292 int pClass = ClassifyPoint(eIPoint, pOrigin, pNormal);
00293
00294 // find the plane intersection point
00295 if (pClass == -1)
00296 { // plane spans sphere
00297
00298 // find plane intersection point by shooting a ray from the
00299 // sphere intersection point along the planes normal.
00300 distToPlaneIntersection = IntersectRayPlane(eIPoint, pNormal, pOrigin, pNormal);
00301
00302 // calculate plane intersection point
00303 pIPoint.x = eIPoint.x + distToPlaneIntersection * pNormal.x;
00304 pIPoint.y = eIPoint.y + distToPlaneIntersection * pNormal.y;
00305 pIPoint.z = eIPoint.z + distToPlaneIntersection * pNormal.z;
00306 }
00307
00308 // find polygon intersection point. By default we assume its equal to the
00309 // plane intersection point. In that case we already know the distance to it.
00310 polyIPoint = pIPoint;
00311 distToSphereIntersection = distToPlaneIntersection;
00312
00313 VECTOR a, b, c;
00314 a.x = polygon[i].Vertex[0].x;
00315 a.y = polygon[i].Vertex[0].y;
00316 a.z = polygon[i].Vertex[0].z;
00317 b.x = polygon[i].Vertex[1].x;
00318 b.y = polygon[i].Vertex[1].y;
00319 b.z = polygon[i].Vertex[1].z;
00320 c.x = polygon[i].Vertex[2].x;
00321 c.y = polygon[i].Vertex[2].y;
00322 c.z = polygon[i].Vertex[2].z;
00323
00324 if(!CheckPointInTriangle(pIPoint, a, b, c))
00325 {
00326 // if not in triangle
00327 polyIPoint = ClosestPointOnPolygon(a, b, c, pIPoint);
00328
00329 VECTOR invertednormalizedVelocity;
00330 invertednormalizedVelocity.x = -normalizedVelocity.x;
00331 invertednormalizedVelocity.y = -normalizedVelocity.y;
00332 invertednormalizedVelocity.z = -normalizedVelocity.z;
00333 distToSphereIntersection = IntersectRaySphere(polyIPoint, invertednormalizedVelocity, source, 1.0f);
00334
00335 // we cannot know if the ray will actually hit the sphere so we need this check
00336 if (distToSphereIntersection > 0)
00337 {
00338 // calculate true ellipsoid intersection point
00339 eIPoint.x = polyIPoint.x + distToSphereIntersection * invertednormalizedVelocity.x;
00340 eIPoint.y = polyIPoint.y + distToSphereIntersection * invertednormalizedVelocity.y;
00341 eIPoint.z = polyIPoint.z + distToSphereIntersection * invertednormalizedVelocity.z;
00342 }
00343 }
00344
00345 // any chance of hit ?
00346 if ((distToSphereIntersection > 0) && (distToSphereIntersection <= MagnitudeVector(velocity)))
00347 {
00348 // if first hit, or closest hit so far
00349 if ((colPackage->foundCollision == FALSE) || (distToSphereIntersection < colPackage->nearestDistance))
00350 {
00351 colPackage->nearestDistance = distToSphereIntersection;
00352 colPackage->nearestSphereIntersectionPoint = eIPoint;
00353 colPackage->nearestPolygonIntersectionPoint = polyIPoint;
00354 colPackage->foundCollision = TRUE;
00355 }
00356 }
00357 }
00358 }
00359
00360 if (!colPackage->foundCollision)
00361 return;
00362
00363 //Collision response
00364
00365 // OK, first task is to move close to where we hit something :
00366 VECTOR newSourcePoint;
00367
00368 // only update if we are not already very close
00369 if (colPackage->nearestDistance >= epsilon)
00370 {
00371
00372 VECTOR V = velocity;
00373 SetLength(V, colPackage->nearestDistance-epsilon);
00374 newSourcePoint.x = source.x + V.x;
00375 newSourcePoint.y = source.y + V.y;
00376 newSourcePoint.z = source.z + V.z;
00377 }
00378 else
00379 newSourcePoint = source;
00380
00381 // Determine the sliding plane (we do this now, because we're about to
00382 // change sourcePoint)
00383 VECTOR slidePlaneOrigin = colPackage->nearestPolygonIntersectionPoint;
00384 VECTOR slidePlaneNormal;
00385 slidePlaneNormal.x = newSourcePoint.x - colPackage->nearestPolygonIntersectionPoint.x;
00386 slidePlaneNormal.y = newSourcePoint.y - colPackage->nearestPolygonIntersectionPoint.y;
00387 slidePlaneNormal.z = newSourcePoint.z - colPackage->nearestPolygonIntersectionPoint.z;
00388 // We now project the destination point onto the sliding plane
00389 float l = IntersectRayPlane(*destination, slidePlaneNormal, slidePlaneOrigin, slidePlaneNormal);
00390 VECTOR newDestinationPoint;
00391 newDestinationPoint.x = destination->x + l * slidePlaneNormal.x;
00392 newDestinationPoint.y = destination->y + l * slidePlaneNormal.y;
00393 newDestinationPoint.z = destination->z + l * slidePlaneNormal.z;
00394
00395 VECTOR newVelocityVector;
00396 newVelocityVector.x = newDestinationPoint.x - colPackage->nearestPolygonIntersectionPoint.x;
00397 newVelocityVector.y = newDestinationPoint.y - colPackage->nearestPolygonIntersectionPoint.y;
00398 newVelocityVector.z = newDestinationPoint.z - colPackage->nearestPolygonIntersectionPoint.z;
00399
00400 destination->x = newSourcePoint.x + newVelocityVector.x;
00401 destination->y = newSourcePoint.y + newVelocityVector.y;
00402 destination->z = newSourcePoint.z + newVelocityVector.z;
00403 colPackage->sourcePoint = newSourcePoint;
00404 colPackage->velocity = newVelocityVector;
00405 colPackage->foundCollision = 0;
00406 CheckForCollision(polygon, destination, colPackage);
00407 }
|
|
||||||||||||||||
|
Definition at line 189 of file collision.cpp. References FALSE, MagnitudeVector(), TRUE, VECTOR::x, VECTOR::y, and VECTOR::z.
|
|
||||||||||||||||||||
|
Definition at line 71 of file collision.cpp. References DotProduct(), GetUnitVector(), VECTOR::x, VECTOR::y, and VECTOR::z. Referenced by CheckForCollision().
00072 {
00073
00074 float total_angles = 0.0f;
00075
00076 // make the 3 vectors
00077 VECTOR TempVect;
00078 TempVect.x = point.x - a.x;
00079 TempVect.y = point.y - a.y;
00080 TempVect.z = point.z - a.z;
00081 VECTOR v1 = TempVect;
00082 TempVect.x = point.x - b.x;
00083 TempVect.y = point.y - b.y;
00084 TempVect.z = point.z - b.z;
00085 VECTOR v2 = TempVect;
00086 TempVect.x = point.x - c.x;
00087 TempVect.y = point.y - c.y;
00088 TempVect.z = point.z - c.z;
00089 VECTOR v3 = TempVect;
00090
00091 v1 = GetUnitVector(v1);
00092 v2 = GetUnitVector(v2);
00093 v3 = GetUnitVector(v3);
00094 float Dot1 = DotProduct(v1,v2);
00095 if (Dot1 < -1)
00096 Dot1 = -1;
00097 if (Dot1 > 1)
00098 Dot1 = 1;
00099 total_angles += acos(Dot1);
00100 float Dot2 = DotProduct(v2,v3);
00101 if (Dot2 < -1)
00102 Dot2 = -1;
00103 if (Dot2 > 1)
00104 Dot2 = 1;
00105 total_angles += acos(Dot2);
00106 float Dot3 = DotProduct(v3,v1);
00107 if (Dot3 < -1)
00108 Dot3 = -1;
00109 if (Dot3 > 1)
00110 Dot3 = 1;
00111 total_angles += acos(Dot3);
00112
00113 if (fabs(total_angles-2*pi) <= 0.005)
00114 return (TRUE);
00115
00116 return(FALSE);
00117 }
|
|
||||||||||||||||
|
Definition at line 225 of file collision.cpp. References DotProduct(), VECTOR::x, VECTOR::y, and VECTOR::z. Referenced by CheckForCollision(), ClassifyInvertedPortal(), ClassifyPortal(), CreateLightmaps(), FindCurrentLeaf(), InvertPortals(), RenderBSP(), SplitPolygon(), and SplitPortal().
00226 {
00227 VECTOR TempVect;
00228 TempVect.x = pO.x - point.x;
00229 TempVect.y = pO.y - point.y;
00230 TempVect.z = pO.z - point.z;
00231 VECTOR dir = TempVect;
00232 float d = DotProduct(dir, pN);
00233
00234 if (d < -0.01f)
00235 return 1;
00236 else
00237 if (d > 0.01f)
00238 return -1;
00239 return 0;
00240 }
|
|
||||||||||||||||
|
Definition at line 119 of file collision.cpp. References DotProduct(), GetUnitVector(), MagnitudeVector(), VECTOR::x, VECTOR::y, and VECTOR::z. Referenced by ClosestPointOnPolygon().
00120 {
00121 // Determine t (the length of the vector from ‘a’ to ‘p’)
00122 VECTOR TempVect;
00123 TempVect.x = p.x - a.x;
00124 TempVect.y = p.y - a.y;
00125 TempVect.z = p.z - a.z;
00126 VECTOR c = TempVect;
00127 TempVect.x = b.x - a.x;
00128 TempVect.y = b.y - a.y;
00129 TempVect.z = b.z - a.z;
00130 VECTOR V = TempVect;
00131
00132 float d = MagnitudeVector(V);
00133
00134 V = GetUnitVector(V);
00135 double t = DotProduct(V,c);
00136
00137 // Check to see if ‘t’ is beyond the extents of the line segment
00138 if (t < 0.0f) return (a);
00139 if (t > d) return (b);
00140
00141 // Return the point between ‘a’ and ‘b’
00142 //set length of V to t. V is normalized so this is easy
00143 V.x = V.x * t;
00144 V.y = V.y * t;
00145 V.z = V.z * t;
00146
00147 TempVect.x = a.x + V.x;
00148 TempVect.y = a.y + V.y;
00149 TempVect.z = a.z + V.z;
00150 return (TempVect);
00151 }
|
|
||||||||||||||||||||
|
Definition at line 153 of file collision.cpp. References ClosestPointOnLine(), MagnitudeVector(), VECTOR::x, VECTOR::y, and VECTOR::z. Referenced by CheckForCollision().
00154 {
00155
00156 VECTOR Rab = ClosestPointOnLine(a, b, p);
00157 VECTOR Rbc = ClosestPointOnLine(b, c, p);
00158 VECTOR Rca = ClosestPointOnLine(c, a, p);
00159
00160 VECTOR TempVect;
00161 TempVect.x = p.x - Rab.x;
00162 TempVect.y = p.y - Rab.y;
00163 TempVect.z = p.z - Rab.z;
00164 float dAB = MagnitudeVector(TempVect);
00165 TempVect.x = p.x - Rbc.x;
00166 TempVect.y = p.y - Rbc.y;
00167 TempVect.z = p.z - Rbc.z;
00168 float dBC = MagnitudeVector(TempVect);
00169 TempVect.x = p.x - Rca.x;
00170 TempVect.y = p.y - Rca.y;
00171 TempVect.z = p.z - Rca.z;
00172 float dCA = MagnitudeVector(TempVect);
00173
00174 float min = dAB;
00175 VECTOR result = Rab;
00176
00177 if (dBC < min)
00178 {
00179 min = dBC;
00180 result = Rbc;
00181 }
00182
00183 if (dCA < min)
00184 result = Rca;
00185
00186 return (result);
00187 }
|
|
||||||||||||||||||||
|
Definition at line 38 of file collision.cpp. References DotProduct(). Referenced by CheckForCollision().
00039 {
00040
00041 float d = - (DotProduct(pNormal,pOrigin));
00042
00043 float numer = DotProduct(pNormal,rOrigin) + d;
00044 float denom = DotProduct(pNormal,rVector);
00045
00046 if (denom == 0) // normal is orthogonal to vector, cant intersect
00047 return (-1.0f);
00048
00049 return -(numer / denom);
00050 }
|
|
||||||||||||||||||||
|
Definition at line 52 of file collision.cpp. References DotProduct(), MagnitudeVector(), VECTOR::x, VECTOR::y, and VECTOR::z. Referenced by CheckForCollision().
00053 {
00054 VECTOR TempVect;
00055 TempVect.x = sO.x - rO.x;
00056 TempVect.y = sO.y - rO.y;
00057 TempVect.z = sO.z - rO.z;
00058 VECTOR Q = TempVect;
00059
00060 float c = MagnitudeVector(Q);
00061 float v = DotProduct(Q,rV);
00062 float d = sR*sR - (c*c - v*v);
00063
00064 // If there was no intersection, return -1
00065 if (d < 0.0) return (-1.0f);
00066
00067 // Return the distance to the [first] intersecting point
00068 return (v - sqrt(d));
00069 }
|
|
|
Definition at line 20 of file collision.cpp. References FALSE, TRUE, VECTOR::x, VECTOR::y, and VECTOR::z.
|
|
||||||||||||
|
Definition at line 12 of file collision.cpp. References VECTOR::x, VECTOR::y, and VECTOR::z. Referenced by CheckForCollision().
|
|
||||||||||||||||
|
Definition at line 203 of file collision.cpp. References GetUnitVector(), VECTOR::x, VECTOR::y, and VECTOR::z.
00204 {
00205 VECTOR TempVect;
00206 TempVect.x = point.x - eO.x;
00207 TempVect.y = point.y - eO.y;
00208 TempVect.z = point.z - eO.z;
00209 VECTOR p = TempVect;
00210
00211 float a2 = eR.x * eR.x;
00212 float b2 = eR.y * eR.y;
00213 float c2 = eR.z * eR.z;
00214
00215
00216 VECTOR res;
00217 res.x = p.x / a2;
00218 res.y = p.y / b2;
00219 res.z = p.z / c2;
00220
00221 res = GetUnitVector(res);
00222 return (res);
00223 }
|
|
||||||||||||
|
Definition at line 27 of file collision.cpp. References VECTOR::x, VECTOR::y, and VECTOR::z.
|
|
|
Definition at line 10 of file collision.cpp. Referenced by CheckForCollision(). |
1.2.15