void cam_rays_marching() { for (int i = 0; i < h_rays; i++) { for (int j = 0; j < w_rays; j++) { AB_RAY _ray = cam_rays[i * w_rays + j]; Debug.DrawLine(_ray.PA.position, _ray.PB.position, Color.gray); if (is_aabb) { // inter_point inter_p = inter.aabb_intersection(ab_ray , aabb , dcubes); // print("inter_p.p0_w " + inter_p.p0_world ); } else { // obb_intersection(ab_ray , obb); inter_point inter_p = inter.obb_intersection_cube(_ray, obb, dcubes); if (inter_p.p0_exist && inter_p.p1_exist) { rayMarch2(inter_p, step_size, max_distance, max_steps, obb, cam.transform.position); } } } } }
void rayMarch2(inter_point inter_p, float _step_size, float max_distance, int _max_steps, OBB _obb, Vector3 cam_pos) { //z-plane alignment bool use_object = true; Vector3 p0 = inter_p.p0_world; Vector3 p1 = inter_p.p1_world; Vector3 cam = cam_pos; Vector3 z_step = new Vector3(0, 0, max_distance / _max_steps); if (use_object) { p0 = inter_p.p0_object; p1 = inter_p.p1_object; cam = _obb.w2o.MultiplyPoint3x4(cam); // print ("cam in object poistion :" + cam); z_step = _obb.w2o.MultiplyVector(z_step); } //the plane alignment should be calculated on cam pos as origin Vector3 p0_c = p0 - cam; Vector3 z_dir = z_step.normalized; //step on p0-p1 align z Vector3 p_step = p0_c * Vector3.Dot(z_step, z_dir) / Vector3.Dot(p0_c, z_dir); Vector3 p0_z_pro = Vector3.Dot(p0_c, z_dir) * z_dir; float scale_p0 = Vector3.Dot(p0_z_pro, z_dir); float scale_z_step = Vector3.Dot(z_step, z_dir); int scale_p0_z_step = (int)(scale_p0 / scale_z_step); Vector3 z_plane = scale_p0_z_step * z_step; Vector3 p0_new = (int)(scale_p0_z_step) * scale_z_step / scale_p0 * p0_c + cam; int full_step = (int)((p1 - p0).magnitude / p_step.magnitude); for (int i = 0; i < full_step + 1; i++) { Vector3 pos = p0_new + i * p_step; Color c = sample3dTexture(pos); //debug cubes if (dcube_created == false) { // print("pos :" + pos ); // print("color :" + c); DCube pd_t = pool.getDCube(); pd_t.position = use_object ? _obb.o2w.MultiplyPoint3x4(pos) : pos; pd_t.color = c; } } }
void rayMarch(inter_point inter_p, float _step_size, float max_distance, int _max_steps, OBB _obb) { int full_step_w = (int)((inter_p.p1_world - inter_p.p0_world).magnitude / max_distance * _max_steps); // print("_obb.w2o : "+_obb.w2o); // print ("full_step_w :" +full_step_w ); //ray marching in obj for (int i = 0; i < full_step_w; i++) { //object space ab Vector3 full_ray = inter_p.p1_world - inter_p.p0_world; Debug.DrawLine(inter_p.p0_world, inter_p.p1_world, Color.red); // print("full_step_w :" + full_step_w); Vector3 stop_p = inter_p.p0_world + full_ray / full_step_w * i; } }
void cam_handler_marching() { Debug.DrawLine(ab_ray.PA.position, ab_ray.PB.position, Color.white); // draw aabb if (is_aabb) { inter_point inter_p = inter.aabb_intersection(ab_ray, aabb, dcubes); // print("inter_p.p0_w " + inter_p.p0_world ); } else { // obb_intersection(ab_ray , obb); inter_point inter_p = inter.obb_intersection_cube(ab_ray, obb, dcubes); if (inter_p.p0_exist && inter_p.p1_exist) { rayMarch2(inter_p, step_size, max_distance, max_steps, obb, cam.transform.position); } } }
public inter_point obb_intersection_cube(AB_RAY _ray, OBB _box, DCube_Ray _dcubes) { Vector3 _PA_pos_cube = _box.w2o.MultiplyPoint3x4(_ray.PA.position); Vector3 _PB_pos_cube = _box.w2o.MultiplyPoint3x4(_ray.PB.position); //object space Vector3 ray_full = _PB_pos_cube - _PA_pos_cube; Vector3 min_inter, max_inter; // intersection point bool min_exist, max_exist; Vector3 ray_min = _box.min_o - _PA_pos_cube; Vector3 ray_max = _box.max_o - _PA_pos_cube; Vector3 xyz_sclae_min; Vector3 xyz_sclae_max; //full ray on x , y , z value Vector3 ray_projected = new Vector3(ray_full.x, ray_full.y, ray_full.z); ray_projected.x = ray_projected.x == 0?0.0000001f : ray_projected.x; ray_projected.y = ray_projected.y == 0?0.0000001f : ray_projected.y; ray_projected.z = ray_projected.z == 0?0.0000001f : ray_projected.z; float _x1 = ray_min.x / ray_projected.x; float _x2 = ray_max.x / ray_projected.x; xyz_sclae_min.x = _x1 < _x2 ? _x1 : _x2; xyz_sclae_max.x = _x1 > _x2 ? _x1 : _x2; float _y1 = ray_min.y / ray_projected.y; float _y2 = ray_max.y / ray_projected.y; xyz_sclae_min.y = _y1 < _y2 ? _y1 : _y2; xyz_sclae_max.y = _y1 > _y2 ? _y1 : _y2; float _z1 = ray_min.z / ray_projected.z; float _z2 = ray_max.z / ray_projected.z; xyz_sclae_min.z = _z1 < _z2 ? _z1 : _z2; xyz_sclae_max.z = _z1 > _z2 ? _z1 : _z2; float min_scale = Mathf.Max(Mathf.Max(xyz_sclae_min.x, xyz_sclae_min.y), xyz_sclae_min.z); float max_scale = Mathf.Min(Mathf.Min(xyz_sclae_max.x, xyz_sclae_max.y), xyz_sclae_max.z); //two intersect point in object space Vector3 p0_o = _PA_pos_cube + Mathf.Max(Mathf.Max(xyz_sclae_min.x, xyz_sclae_min.y), xyz_sclae_min.z) * ray_full; Vector3 p1_o = _PA_pos_cube + Mathf.Min(Mathf.Min(xyz_sclae_max.x, xyz_sclae_max.y), xyz_sclae_max.z) * ray_full; //two intersect point in object space Vector3 p0_w = _box.o2w.MultiplyPoint3x4(p0_o); Vector3 p1_w = _box.o2w.MultiplyPoint3x4(p1_o); min_exist = false; max_exist = false; if (min_scale < max_scale) { if (min_scale > 0 && min_scale < 1) { min_exist = true; } if (max_scale > 0 && max_scale < 1) { max_exist = true; } } //debug info display _dcubes.p0.position = p0_w; _dcubes.p1.position = p1_w; _dcubes.x0.position = _ray.PA.position + xyz_sclae_min.x * _ray.fullRay; _dcubes.x1.position = _ray.PA.position + xyz_sclae_max.x * _ray.fullRay; _dcubes.y0.position = _ray.PA.position + xyz_sclae_min.y * _ray.fullRay; _dcubes.y1.position = _ray.PA.position + xyz_sclae_max.y * _ray.fullRay; _dcubes.z0.position = _ray.PA.position + xyz_sclae_min.z * _ray.fullRay; _dcubes.z1.position = _ray.PA.position + xyz_sclae_max.z * _ray.fullRay; if (!min_exist) { _dcubes.p0.release(); } else { _dcubes.p0.use(); } if (!max_exist) { _dcubes.p1.release(); } else { _dcubes.p1.use(); } inter_point inter = new inter_point(p0_o, p1_o, p0_w, p1_w, min_exist, max_exist); return(inter); }
public inter_point aabb_intersection(AB_RAY _ray, AABB _box, DCube_Ray _dcubes) { bool min_exist, max_exist; Vector3 ray_min = _box.min - _ray.PA.position; Vector3 ray_max = _box.max - _ray.PA.position; Vector3 xyz_sclae_min; Vector3 xyz_sclae_max; Vector3 fullRay = new Vector3(_ray.fullRay.x == 0? 0.0001f : _ray.fullRay.x, _ray.fullRay.y == 0? 0.0001f : _ray.fullRay.y, _ray.fullRay.z == 0? 0.0001f : _ray.fullRay.z); float _x1 = ray_min.x / _ray.fullRay.x; float _x2 = ray_max.x / _ray.fullRay.x; xyz_sclae_min.x = _x1 < _x2 ? _x1 : _x2; xyz_sclae_max.x = _x1 > _x2 ? _x1 : _x2; float _y1 = ray_min.y / _ray.fullRay.y; float _y2 = ray_max.y / _ray.fullRay.y; xyz_sclae_min.y = _y1 < _y2 ? _y1 : _y2; xyz_sclae_max.y = _y1 > _y2 ? _y1 : _y2; float _z1 = ray_min.z / _ray.fullRay.z; float _z2 = ray_max.z / _ray.fullRay.z; xyz_sclae_min.z = _z1 < _z2 ? _z1 : _z2; xyz_sclae_max.z = _z1 > _z2 ? _z1 : _z2; float min_scale = Mathf.Max(Mathf.Max(xyz_sclae_min.x, xyz_sclae_min.y), xyz_sclae_min.z); float max_scale = Mathf.Min(Mathf.Min(xyz_sclae_max.x, xyz_sclae_max.y), xyz_sclae_max.z); min_exist = false; max_exist = false; if (min_scale < max_scale) { if (min_scale > 0 && min_scale < 1) { min_exist = true; } if (max_scale > 0 && max_scale < 1) { max_exist = true; } } _dcubes.p0.position = _ray.PA.position + min_scale * _ray.fullRay; _dcubes.p1.position = _ray.PA.position + max_scale * _ray.fullRay; _dcubes.x0.position = _ray.PA.position + xyz_sclae_min.x * _ray.fullRay; _dcubes.x1.position = _ray.PA.position + xyz_sclae_max.x * _ray.fullRay; _dcubes.y0.position = _ray.PA.position + xyz_sclae_min.y * _ray.fullRay; _dcubes.y1.position = _ray.PA.position + xyz_sclae_max.y * _ray.fullRay; _dcubes.z0.position = _ray.PA.position + xyz_sclae_min.z * _ray.fullRay; _dcubes.z1.position = _ray.PA.position + xyz_sclae_max.z * _ray.fullRay; if (!min_exist) { _dcubes.p0.release(); } else { _dcubes.p0.use(); } if (!max_exist) { _dcubes.p1.release(); } else { _dcubes.p1.use(); } inter_point inter = new inter_point(Vector3.zero, Vector3.zero, _dcubes.p0.position, _dcubes.p1.position, min_exist, max_exist); return(inter); }