// Trace a line through the world to simulate, eg, a bullet http://www.youtube.com/watch?v=USjbg5QXk3g bool CGame::TraceLine(const Vector& v0, const Vector& v1, Vector& vecIntersection, CCharacter*& pHit) { float flLowestFraction = 1; Vector vecTestIntersection; float flTestFraction; pHit = nullptr; for (size_t i = 0; i < MAX_CHARACTERS; i++) { CCharacter* pCharacter = GetCharacterIndex(i); if (!pCharacter) continue; // Only monsters and boxes get hit by traces. The player doesn't, he's immune to his own attacks. if (!pCharacter->m_bHitByTraces) continue; Matrix4x4 mInverse = pCharacter->GetGlobalTransform().InvertedTR(); // The v0 and v1 are in the global coordinate system and we need to transform it to the target's // local coordinate system to use axis-aligned intersection. We do so using the inverse transform matrix. // http://youtu.be/-Fn4atv2NsQ if (LineAABBIntersection(pCharacter->m_aabbSize, mInverse*v0, mInverse*v1, vecTestIntersection, flTestFraction) && flTestFraction < flLowestFraction) { // Once we have the result we can use the regular transform matrix to get it back in // global coordinates. http://youtu.be/-Fn4atv2NsQ vecIntersection = pCharacter->GetGlobalTransform()*vecTestIntersection; flLowestFraction = flTestFraction; pHit = pCharacter; } } // Intersect with the floor. // Line-Plane Intersection algorithm: http://youtu.be/fIu_8b2n8ZM if (LinePlaneIntersection(Vector(0, 1, 0), Vector(0, 0, 0), v0, v1, vecTestIntersection, flTestFraction) && flTestFraction < flLowestFraction) { vecIntersection = vecTestIntersection; flLowestFraction = flTestFraction; pHit = nullptr; } if (flLowestFraction < 1) return true; return false; }
bool RayIntersectTriangle(Vector3 rayStart, Vector3 rayDirection, Vector3 a, Vector3 b, Vector3 c) { float t; Vector3 ba = b - a; Vector3 cb = c - b; Vector3 ac = a - c; Vector3 normal = ba.Cross(ac); if (LinePlaneIntersection(rayStart, rayDirection, a, normal, t)) { if (t >= 0.f) { Vector3 q = rayStart + t * rayDirection; Vector3 qa = q - a; Vector3 qb = q - b; Vector3 qc = q - c; return ba.Cross(qa).Dot(normal) >= 0 && cb.Cross(qb).Dot(normal) >= 0 && ac.Cross(qc).Dot(normal) >= 0; } // Behind the ray return false; } // Parallel return false; }
static void generated_grid(const char* OutPutFile, GzRender* renderer) { static float up_bias = 30.0f, forward_bias = 20.0f; float u, v; float meshTri1V1[4]; float meshTri1V2[4]; float meshTri1V3[4]; float meshTri2V1[4]; float meshTri2V2[4]; float meshTri2V3[4]; xRes = 1.0f/RECT_MAX_X; yRes = 1.0f/RECT_MAX_Z; CTransMatrix MProjection; CTransMatrix XiwTrans, XpiTrans; //set Xsp, Ximage elements GzCoord view_vector; VectorSubtract(renderer->camera.lookat, renderer->camera.position, view_vector); Normalize(view_vector); if(view_vector[1] < 0.0f) //look at y=0 { GzCoord camera_pos; Scale(renderer->camera.position, 1.0f, camera_pos); renderer->camera.position[1] = camera_pos[1] + up_bias; renderer->camera.lookat[0] = camera_pos[0] - camera_pos[1]/view_vector[1]*view_vector[0]; renderer->camera.lookat[1] = 0.0f; renderer->camera.lookat[2] = camera_pos[2] - camera_pos[1]/view_vector[1]*view_vector[2]; GzPutCamera(renderer, &renderer->camera); } else //look away from y=0 { GzCoord camera_pos; Scale(renderer->camera.position, 1.0f, camera_pos); GzCoord camera_forward = {view_vector[0], 0.0f, view_vector[2]}; Normalize(camera_forward); renderer->camera.position[1] = camera_pos[1] + up_bias; renderer->camera.lookat[0] = camera_pos[0] + forward_bias * camera_forward[0]; renderer->camera.lookat[1] = 0.0f; renderer->camera.lookat[2] = camera_pos[2] + forward_bias * camera_forward[2]; GzPutCamera(renderer, &renderer->camera); } for (int i=0;i<4;i++) { for (int j=0;j<4;j++) { XiwTrans.SetElementValue(i,j,(double)renderer->camera.Xiw[i][j]); XpiTrans.SetElementValue(i,j,(double)renderer->camera.Xpi[i][j]); } } MProjection = XpiTrans; MProjection *=XiwTrans; MatrixInverse(MProjection.matrixData, MProjection.matrixData); //transform and output the vertices FILE *outfile ; outfile = fopen ( OutPutFile , "wb" ); //Transform four corners of the grid float leftbottomper[4] = {-1.0f, -1.0f, -1.0f, 1.0f}, rightbottomper[4] = {1.0f, -1.0f, -1.0f, 1.0f}, lefttopper[4] = {-1.0f, 1.0f, -1.0f, 1.0f}, righttopper[4] = {1.0f, 1.0f, -1.0f, 1.0f}; float leftbottom1[4], rightbottom1[4], lefttop1[4], righttop1[4]; float leftbottom2[4], rightbottom2[4], lefttop2[4], righttop2[4]; //transform leftbottom to world space //set z to -1 leftbottomper[2] = -1; MProjection.GetTransformedHVertex(leftbottomper,leftbottom1); leftbottomper[2] = 1; MProjection.GetTransformedHVertex(leftbottomper,leftbottom2); LinePlaneIntersection(leftbottom1, leftbottom2, m_LeftBottom); //transform rightbottom to world space rightbottomper[2] = -1; MProjection.GetTransformedHVertex(rightbottomper,rightbottom1); rightbottomper[2] = 1; MProjection.GetTransformedHVertex(rightbottomper,rightbottom2); LinePlaneIntersection(rightbottom1, rightbottom2, m_RightBottom); //transform lefttop to world space lefttopper[2] = -1; MProjection.GetTransformedHVertex(lefttopper,lefttop1); lefttopper[2] = 1; MProjection.GetTransformedHVertex(lefttopper,lefttop2); LinePlaneIntersection(lefttop1, lefttop2, m_LeftTop); //transform righttop to world space righttopper[2] = -1; MProjection.GetTransformedHVertex(righttopper,righttop1); righttopper[2] = 1; MProjection.GetTransformedHVertex(righttopper,righttop2); LinePlaneIntersection(righttop1, righttop2, m_RightTop); //interpolate homegeneous coordinates float current_Vertex[4]; for (int i=0; i<RECT_MAX_X;i++ ) { for (int j=0;j<RECT_MAX_Z;j++) { fprintf( outfile, "Triangle\r\n"); InterpolateHomoCoord(i,j,meshTri1V1); u = i*xRes; v= j*yRes; fprintf( outfile, "%f %f %f " , meshTri1V1[X], meshTri1V1[Y], meshTri1V1[Z] ); fprintf( outfile, "0.00 1.00 0.00 ");//normal fprintf( outfile, "%f %f\r\n", u,v); InterpolateHomoCoord(i+1,j,meshTri1V2); u = (i+1)*xRes; v= j*yRes; fprintf( outfile, "%f %f %f " , meshTri1V2[X], meshTri1V2[Y], meshTri1V2[Z] ); fprintf( outfile, "0.00 1.00 0.00 ");//normal fprintf( outfile, "%f %f\r\n", u,v); InterpolateHomoCoord(i+1,j+1,meshTri1V3); u = (i+1)*xRes; v= (j+1)*yRes; fprintf( outfile, "%f %f %f " , meshTri1V3[X], meshTri1V3[Y], meshTri1V3[Z] ); fprintf( outfile, "0.00 1.00 0.00 ");//normal fprintf( outfile, "%f %f\r\n", u,v); //Second triangle vertices fprintf( outfile, "Triangle\r\n"); u = i*xRes; v= j*yRes; fprintf( outfile, "%f %f %f " , meshTri1V1[X], meshTri1V1[Y], meshTri1V1[Z] ); fprintf( outfile, "0.00 1.00 0.00 ");//normal fprintf( outfile, "%f %f\r\n", u,v); u = (i+1)*xRes; v= (j+1)*yRes; fprintf( outfile, "%f %f %f " , meshTri1V3[X], meshTri1V3[Y], meshTri1V3[Z] ); fprintf( outfile, "0.00 1.00 0.00 ");//normal fprintf( outfile, "%f %f\r\n", u,v); InterpolateHomoCoord(i,j+1,meshTri2V3); u = i*xRes; v= (j+1)*yRes; fprintf( outfile, "%f %f %f " , meshTri2V3[X], meshTri2V3[Y], meshTri2V3[Z] ); fprintf( outfile, "0.00 1.00 0.00 ");//normal fprintf( outfile, "%f %f\r\n", u,v); } } }