void start(const Vec3& position, const Vec3& direction, float range) { this->start_position = position; this->direction = direction; IF_ASSERT(vec3_length_squared(direction) == 0) this->direction = vec3_init(0, 0, 1); this->range = range; }
bool hitscan_sprite_mobs(const Vec3& position, const Vec3& direction, float range, SpriteMobID& id, float& distance, Vec3& collision_point) { SpriteMobID nearest_mob = NULL_SPRITE_MOB; float nearest_distance = 100000.0f; Vec3 nearest_collision_point = vec3_init(0); const float range_sq = range * range; const Vec3 up = vec3_init(0, 0, 1); for (size_t i=0, j=0; i<sprite_mob_list->max && j<sprite_mob_list->count; i++) { // TODO // do a line-plane intersection test against the mob, if its in frustum SpriteMob* m = sprite_mob_list->objects[i]; if (m == NULL) continue; j++; Vec3 p = m->get_center(); p = quadrant_translate_position(position, p); if (vec3_distance_squared(position, p) > range_sq) continue; float rad_sq = 10000.0f; Vec3 line_point = vec3_init(0); if (!sphere_line_distance(position, direction, p, line_point, rad_sq)) continue; Vec3 forward = vec3_sub(position, p); forward.z = 0.0f; if (unlikely(vec3_length_squared(forward) == 0)) continue; forward = vec3_normalize(forward); const Vec3 right = vec3_normalize(vec3_cross(forward, up)); float d = 1000000.0f; float width = get_mob_width(m->type) * 0.5f; float height = get_mob_height(m->type) * 0.5f; if (!line_plane_intersection(position, direction, p, width, height, forward, right, up, d)) continue; if (d >= nearest_distance) continue; nearest_distance = d; nearest_mob = m->id; nearest_collision_point = line_point; } id = nearest_mob; distance = nearest_distance; collision_point = translate_position(nearest_collision_point); return (nearest_mob != NULL_SPRITE_MOB); }
int scene_sphere_is_point_in_solid(const Scene* scene, const Vec3* point) { const Sphere* sphere = (const Sphere*)scene->data; Vec3 tmp = vec3_sub(point, &sphere->centre); return vec3_length_squared(&tmp) <= sphere->radius * sphere->radius; }