//clips an edge against one plane. vertex *clip_edge(int plane_flag,vertex *on_pnt,vertex *off_pnt, uint flags) { float ratio; vertex *tmp; tmp = get_temp_point(); if ( plane_flag & CC_OFF_USER ) { // Clip with user-defined plane vector w, ray_direction; float num,den; vm_vec_sub(&ray_direction,(vector *)&off_pnt->x,(vector *)&on_pnt->x); vm_vec_sub(&w,(vector *)&on_pnt->x,&G3_user_clip_point); den = -vm_vec_dot(&G3_user_clip_normal,&ray_direction); if ( den == 0.0f ) { // Ray & plane are parallel, so there is no intersection Int3(); // Get John ratio = 1.0f; } else { num = vm_vec_dot(&G3_user_clip_normal,&w); ratio = num / den; } tmp->x = on_pnt->x + (off_pnt->x-on_pnt->x) * ratio; tmp->y = on_pnt->y + (off_pnt->y-on_pnt->y) * ratio; tmp->z = on_pnt->z + (off_pnt->z-on_pnt->z) * ratio; } else { float a,b,kn,kd; //compute clipping value k = (xs-zs) / (xs-xe-zs+ze) //use x or y as appropriate, and negate x/y value as appropriate if (plane_flag & (CC_OFF_RIGHT | CC_OFF_LEFT)) { a = on_pnt->x; b = off_pnt->x; } else { a = on_pnt->y; b = off_pnt->y; } if (plane_flag & (CC_OFF_LEFT | CC_OFF_BOT)) { a = -a; b = -b; } kn = a - on_pnt->z; //xs-zs kd = kn - b + off_pnt->z; //xs-zs-xe+ze ratio = kn / kd; tmp->x = on_pnt->x + (off_pnt->x-on_pnt->x) * ratio; tmp->y = on_pnt->y + (off_pnt->y-on_pnt->y) * ratio; if (plane_flag & (CC_OFF_TOP|CC_OFF_BOT)) { tmp->z = tmp->y; } else { tmp->z = tmp->x; } if (plane_flag & (CC_OFF_LEFT|CC_OFF_BOT)) tmp->z = -tmp->z; } if (flags & TMAP_FLAG_TEXTURED) { tmp->u = on_pnt->u + (off_pnt->u-on_pnt->u) * ratio; tmp->v = on_pnt->v + (off_pnt->v-on_pnt->v) * ratio; tmp->env_u = on_pnt->env_u + (off_pnt->env_u-on_pnt->env_u) * ratio; tmp->env_v = on_pnt->env_v + (off_pnt->env_v-on_pnt->env_v) * ratio; } if (flags & TMAP_FLAG_GOURAUD ) { if (flags & TMAP_FLAG_RAMP) { float on_b, off_b; on_b = i2fl(on_pnt->b); off_b = i2fl(off_pnt->b); tmp->b = ubyte(fl2i(on_b + (off_b-on_b) * ratio)); } if (flags & TMAP_FLAG_RGB) { float on_r, on_b, on_g, onspec_r, onspec_g, onspec_b; float off_r, off_b, off_g, offspec_r, offspec_g, offspec_b; on_r = i2fl(on_pnt->r); off_r = i2fl(off_pnt->r); on_g = i2fl(on_pnt->g); off_g = i2fl(off_pnt->g); on_b = i2fl(on_pnt->b); off_b = i2fl(off_pnt->b); onspec_r = i2fl(on_pnt->spec_r); offspec_r = i2fl(off_pnt->spec_r); onspec_g = i2fl(on_pnt->spec_g); offspec_g = i2fl(off_pnt->spec_g); onspec_b = i2fl(on_pnt->spec_b); offspec_b = i2fl(off_pnt->spec_b); tmp->r = ubyte(fl2i(on_r + (off_r-on_r) * ratio)); tmp->g = ubyte(fl2i(on_g + (off_g-on_g) * ratio)); tmp->b = ubyte(fl2i(on_b + (off_b-on_b) * ratio)); tmp->spec_r = ubyte(fl2i(onspec_r + (offspec_r-onspec_r) * ratio)); tmp->spec_g = ubyte(fl2i(onspec_g + (offspec_g-onspec_g) * ratio)); tmp->spec_b = ubyte(fl2i(onspec_b + (offspec_b-onspec_b) * ratio)); } } else { tmp->spec_r=tmp->spec_g=tmp->spec_b=0; } if (flags & TMAP_FLAG_ALPHA) { float on_a, off_a; on_a = i2fl(on_pnt->a); off_a = i2fl(off_pnt->a); tmp->a = ubyte(fl2i(on_a + (off_a-on_a) * ratio)); } g3_code_vertex(tmp); return tmp; }
//clips an edge against one plane. g3s_point *clip_edge(int plane_flag,g3s_point *on_pnt,g3s_point *off_pnt) { fix psx_ratio; fix a,b,kn,kd; g3s_point *tmp; //compute clipping value k = (xs-zs) / (xs-xe-zs+ze) //use x or y as appropriate, and negate x/y value as appropriate if (plane_flag & (CC_OFF_RIGHT | CC_OFF_LEFT)) { a = on_pnt->p3_x; b = off_pnt->p3_x; } else { a = on_pnt->p3_y; b = off_pnt->p3_y; } if (plane_flag & (CC_OFF_LEFT | CC_OFF_BOT)) { a = -a; b = -b; } kn = a - on_pnt->p3_z; //xs-zs kd = kn - b + off_pnt->p3_z; //xs-zs-xe+ze tmp = get_temp_point(); psx_ratio = fixdiv( kn, kd ); // PSX_HACK!!!! // tmp->p3_x = on_pnt->p3_x + fixmuldiv(off_pnt->p3_x-on_pnt->p3_x,kn,kd); // tmp->p3_y = on_pnt->p3_y + fixmuldiv(off_pnt->p3_y-on_pnt->p3_y,kn,kd); tmp->p3_x = on_pnt->p3_x + fixmul( (off_pnt->p3_x-on_pnt->p3_x), psx_ratio); tmp->p3_y = on_pnt->p3_y + fixmul( (off_pnt->p3_y-on_pnt->p3_y), psx_ratio); if (plane_flag & (CC_OFF_TOP|CC_OFF_BOT)) tmp->p3_z = tmp->p3_y; else tmp->p3_z = tmp->p3_x; if (plane_flag & (CC_OFF_LEFT|CC_OFF_BOT)) tmp->p3_z = -tmp->p3_z; if (on_pnt->p3_flags & PF_UVS) { // PSX_HACK!!!! // tmp->p3_u = on_pnt->p3_u + fixmuldiv(off_pnt->p3_u-on_pnt->p3_u,kn,kd); // tmp->p3_v = on_pnt->p3_v + fixmuldiv(off_pnt->p3_v-on_pnt->p3_v,kn,kd); tmp->p3_u = on_pnt->p3_u + fixmul((off_pnt->p3_u-on_pnt->p3_u), psx_ratio); tmp->p3_v = on_pnt->p3_v + fixmul((off_pnt->p3_v-on_pnt->p3_v), psx_ratio); tmp->p3_flags |= PF_UVS; } if (on_pnt->p3_flags & PF_LS) { // PSX_HACK // tmp->p3_r = on_pnt->p3_r + fixmuldiv(off_pnt->p3_r-on_pnt->p3_r,kn,kd); // tmp->p3_g = on_pnt->p3_g + fixmuldiv(off_pnt->p3_g-on_pnt->p3_g,kn,kd); // tmp->p3_b = on_pnt->p3_b + fixmuldiv(off_pnt->p3_b-on_pnt->p3_b,kn,kd); tmp->p3_l = on_pnt->p3_l + fixmul((off_pnt->p3_l-on_pnt->p3_l), psx_ratio); tmp->p3_flags |= PF_LS; } G3EncodePoint(tmp); return tmp; }