Math::cVector CollisionDetection::CollideWithWorld(Math::cVector& position, Math::cVector& velocity,float length,bool isCamCollision) { if (velocity.GetLength() == 0) return position; CollisionData coll; coll.foundCollision = false; coll.nearestDistance = 0; coll.sourcepoint = position; coll.velocity = velocity.CreateNormalized(); coll.length = length; for (int j = 0; j < mVertexPosition.size(); j += 3) { Math::cVector planeOrigin = mVertexPosition[mVertexIndices[j]]; Math::cVector B = mVertexPosition[mVertexIndices[j + 1]]; Math::cVector C =mVertexPosition[mVertexIndices[j + 2]]; RayTriangleIntersection(planeOrigin,B,C, length, &coll); } if (!isCamCollision) return ResolvePlayerCollision(position,velocity, coll); else return ResolveCameraCollision(position,velocity, coll); }
void eae6320::Graphics::traceRayHorizontal(float& timeCollided) { float shortestTime = FLT_MAX; Math::cVector intersectionPoint; Math::cVector normalAtIntersection; Math::cVector parallelStart = gameObjects[0]->camObject->position; /*Math::cVector parallelEnd = gameObjects[0]->camObject->position + gameObjects[0]->camObject->velocity + gameObjects[0]->camObject->acceleration * timeLeftInFrame * timeLeftInFrame * 0.5f;*/ Math::cVector parallelEnd = gameObjects[0]->camObject->position +10.0f; bool intersected = false; float shortestTimeReal = FLT_MAX; for (int i = 0; i < context.numberOfIndices; i += 3) { int index = context.indexData[i]; int index1 = context.indexData[i + 1]; int index2 = context.indexData[i + 2]; eae6320::Math::cVector vertexA = eae6320::Math::cVector(context.vertexData[index].x, context.vertexData[index].y, context.vertexData[index].z); eae6320::Math::cVector vertexB = eae6320::Math::cVector(context.vertexData[index1].x, context.vertexData[index1].y, context.vertexData[index1].z); eae6320::Math::cVector vertexC = eae6320::Math::cVector(context.vertexData[index2].x, context.vertexData[index2].y, context.vertexData[index2].z); eae6320::Math::cVector normal = eae6320::Math::cVector(context.vertexData[i].nx, context.vertexData[i].ny, context.vertexData[i].nz); float u = 0, v = 0, w = 0, t = 0; int a = IntersectSegmentTriangle(parallelStart, parallelEnd, vertexA, vertexC, vertexB, u, v, w, t,normal); //normal = eae6320::Math::cVector(context.vertexData[i].nx, context.vertexData[i].ny, context.vertexData[i].nz); if (a == 1) { if (t < shortestTime) { shortestTime = t; //intersectionPoint = vertexA*u + vertexB*v + vertexC*w; intersectionPoint = parallelStart + (parallelEnd - parallelStart) * t; //normalAtIntersection = normal * -1.0f; shortestTimeReal = (intersectionPoint - parallelStart).GetLength() / (parallelStart - parallelEnd).GetLength(); intersected = true; } } } if (intersected) { float oneByNormal = 1 /( normalAtIntersection.GetLength()); Math::cVector verticalProjectionAcceleration = normalAtIntersection * eae6320::Math::Dot(gameObjects[0]->camObject->acceleration, normalAtIntersection)*oneByNormal*oneByNormal; gameObjects[0]->camObject->acceleration = gameObjects[0]->camObject->acceleration - verticalProjectionAcceleration; Math::cVector verticalProjectionVelocity = normalAtIntersection * eae6320::Math::Dot(gameObjects[0]->camObject->velocity, normalAtIntersection)*oneByNormal*oneByNormal; gameObjects[0]->camObject->velocity = gameObjects[0]->camObject->velocity - verticalProjectionVelocity; gameObjects[0]->camObject->position = intersectionPoint - normalAtIntersection.CreateNormalized(); timeCollided = shortestTimeReal; } }
void eae6320::Graphics::DoCOllisions(GameObject* player) { // COllision Detection player->m_velocity = player->m_position - s_playerPrevPos; player->m_position = s_collisionDet->CollideWithWorld(player->m_position, player->m_velocity, 50, false); player->m_velocity = Math::cVector(0, -9.8f, 0) * 5; player->m_position = s_collisionDet->CollideWithWorld(player->m_position, player->m_velocity, 20, false); s_playerPrevPos = player->m_position; Math::cVector playerDir = player->m_position - s_camera->m_position; Math::cMatrix_transformation mat = Math::cMatrix_transformation::cMatrix_transformation(player->m_orientation, player->m_position); Math::cVector offset = Math::cMatrix_transformation::matrixMulVector(mat, Math::cVector(0, 120, 200)); Math::cVector rayOrigin = offset; s_collisionDet->CollideWithWorld(rayOrigin, playerDir, playerDir.GetLength(), true); }
bool CollisionDetection::CheckIfPointInTriangle(Math::cVector &polygonInterectionPoint, Math::cVector &vertex1, Math::cVector &vertex2, Math::cVector &vertex3) { float totalAngles=0; Math::cVector A = polygonInterectionPoint - vertex1; Math::cVector B = polygonInterectionPoint - vertex2; Math::cVector C = polygonInterectionPoint - vertex3; A = A.CreateNormalized(); B = B.CreateNormalized(); C= C.CreateNormalized(); float Dot1 = Math::Dot(A, B); if (Dot1 < -1) Dot1 = -1; if (Dot1 > 1) Dot1 = 1; totalAngles += acos(Dot1); float Dot2 = Math::Dot(B, C); if (Dot2 < -1) Dot2 = -1; if (Dot2 > 1) Dot2 = 1; totalAngles += acos(Dot2); float Dot3 = Math::Dot(A, C); if (Dot3 < -1) Dot3 = -1; if (Dot3 > 1) Dot3 = 1; totalAngles += acos(Dot3); if (fabs(totalAngles - 2 * 3.14159265f) <= 0.005f) { return true; } return false; }
int CollisionDetection::RayTriangleIntersection(Math::cVector& v1, Math::cVector& v2, Math::cVector& v3,float length, CollisionData *collD) { Math::cVector e1, e2; e1 = v2 - v1; e2 = v3 - v1; /* Math::cVector n = Math::Cross(e1, e2); n = n.CreateNormalized(); float det = Math::Dot(n, collD->velocity ); if (det <= 0.0f) return 0; float inv_det = 1 / det; Math::cVector sourceToVertex = v1 - collD->sourcepoint; float e = Math::Dot(sourceToVertex,n); if (e < 0.0f) return 0; //if (e > collD->length) //return 0; Math::cVector o = Math::Cross(collD->velocity ,sourceToVertex); float v = Math::Dot(e2,o); if (v<0.0f || v>collD->length) return 0; float w = -Math::Dot(e1,o); if (w<0.0f || v + w>collD->length) return 0; e *= inv_det; v *= inv_det; w *= inv_det; float u = 1.0f - v - w; return 1; */ Math::cVector n = Math::Cross(e1, e2); n = n.CreateNormalized(); Math::cVector ePoint = collD->sourcepoint;// -n; float det = Math::Dot(n, collD->velocity ); if (det == 0.0f) return 0; float inv_det = 1 / det; float a = Math::Dot(v1,n); float b = Math::Dot(n, ePoint); float t = (a - b) * inv_det; if (t < 0) return 0; if (t > 0 && t <= collD->length) { Math::cVector collPnt = ePoint + (collD->velocity * t); if (CheckIfPointInTriangle(collPnt, v1, v2, v3)) { { collD->nearestPloygonIntersectionPoint = collPnt; collD->collNormal = n; collD->foundCollision = true; collD->nearestDistance = t; return 1; } } } return 0; }