/* ============== Terrain_Ray Itersects a ray with a terrain Returns the face hit and the distance along the ray the intersection occured at Returns NULL and 0 if not hit at all ============== */ terrainFace_t *Terrain_Ray( vec3_t origin, vec3_t dir, brush_t *b, float *dist ) { terrainMesh_t *pm; int h; int w; int x; int y; float best_t; float t; terravert_t a0; terravert_t a1; terravert_t a2; terravert_t b0; terravert_t b1; terravert_t b2; terrainVert_t *vert; terrainFace_t *best; best = NULL; best_t = WORLD_SIZE * 2; pm = b->pTerrain; h = pm->height - 1; w = pm->width - 1; vert = pm->heightmap; for( y = 0; y < h; y++, vert++ ) { for( x = 0; x < w; x++, vert++ ) { Terrain_GetTriangles( pm, x, y, &a0, &a1, &a2, &b0, &b1, &b2, NULL ); t = WORLD_SIZE * 2; if ( RayTriangleIntersect( origin, dir, a2.xyz, a1.xyz, a0.xyz, &t ) ) { if ( ( t >= 0 ) && ( t < best_t ) ) { best = &vert->tri; best_t = t; } } t = WORLD_SIZE * 2; if ( RayTriangleIntersect( origin, dir, b2.xyz, b1.xyz, b0.xyz, &t ) ) { if ( ( t >= 0 ) && ( t < best_t ) ) { best = &vert->tri; best_t = t; } } } } if ( !best ) { *dist = 0; return NULL; } *dist = best_t; return best; }
float Animated_Mesh::Ray_Tri_Intersect(const vec3& rayorig, const vec3& raydir) { mat4 inverseW(GetWorld()); inverseW.inverse(); vec3 org(rayorig*inverseW), di(raydir);// transform these to the mesh's space so the checks are in object space, not world space TransformNormal(di, inverseW); // do all checks in OBJECT SPACE!!! di*=20000.0f;//make sure the ray is long enough if(Bounding_Volume.RayIntersect(org, di) == INFINITY) return INFINITY;// did not hit the aabb, therefore, we did not hit the object if(IB.Stride == 4){ return RayTriangleIntersect(org, di, &Vertices[0], reinterpret_cast<const uint32_t*>(&Indices[0]),Indices.size()/2); } else { return RayTriangleIntersect(org, di, &Vertices[0],&Indices[0],Indices.size()); } }
float Trans_Mesh::Ray_Tri_Intersect(const vec3& rayorig, const vec3& raydir, mat4& world, uint16_t startindex, uint16_t numindices) const{ world.inverse(); vec3 org(rayorig*world), di(raydir);// transform these to the mesh's space so the checks are in object space, not world space TransformNormal(di, world); // do all checks in OBJECT SPACE!!! di*=20000.0f;//make sure the ray is long enough return RayTriangleIntersect(org, di, &Vertices[0], &Indices[startindex],numindices); }