int Polygon_IsBroken(polygon_p p) { float dif[3]; vertex_p next_v, curr_v; if(p->vertex_count < 3) { return 1; } dif[0] = vec3_sqabs(p->plane); if(dif[0] < 0.999 || dif[0] > 1.001) { return 1; } next_v = p->vertices; curr_v = p->vertices + p->vertex_count - 1; for(uint16_t i = 0; i < p->vertex_count; i++) { vec3_sub(dif, next_v->position, curr_v->position); if(vec3_sqabs(dif) < 0.0001) { return 1; } curr_v = next_v; next_v ++; } return 0; }
void SSBoneFrame_TargetBoneToSlerp(struct ss_bone_frame_s *bf, struct ss_animation_s *ss_anim) { extern float engine_frame_time; if(ss_anim->anim_ext_flags & ANIM_EXT_TARGET_TO) { ss_bone_tag_p b_tag = bf->bone_tags + ss_anim->targeting_bone; float clamped_q[4], q[4], target_dir[3], target_local[3], bone_dir[3]; Mat4_vec3_mul_inv(target_local, bf->transform, ss_anim->target); if(b_tag->parent) { Mat4_vec3_mul_inv(target_local, b_tag->parent->full_transform, target_local); } vec3_sub(target_dir, target_local, b_tag->transform + 12); if(ss_anim->targeting_flags & ANIM_TARGET_OWERRIDE_ANIM) { Mat4_vec3_rot_macro(bone_dir, b_tag->transform, ss_anim->bone_direction); } else { vec3_copy(bone_dir, ss_anim->bone_direction); } vec4_GetQuaternionRotation(q, bone_dir, target_dir); if(ss_anim->targeting_flags & ANIM_TARGET_USE_AXIS_MOD) { q[0] *= ss_anim->targeting_axis_mod[0]; q[1] *= ss_anim->targeting_axis_mod[1]; q[2] *= ss_anim->targeting_axis_mod[2]; q[3] = 1.0f - vec3_sqabs(q); q[3] = sqrtf(q[3]); } if(q[3] < ss_anim->targeting_limit[3]) { vec4_clampw(q, ss_anim->targeting_limit[3]); } vec4_slerp_to(clamped_q, ss_anim->current_mod, q, engine_frame_time * M_PI / 1.3f); vec4_copy(ss_anim->current_mod, clamped_q); SSBoneFrame_RotateBone(bf, ss_anim->current_mod, ss_anim->targeting_bone); } else if(ss_anim->current_mod[3] < 1.0f) { if(ss_anim->current_mod[3] < 0.99f) { float zero_ang[4] = {0.0f, 0.0f, 0.0f, 1.0f}; float clamped_q[4]; vec4_slerp_to(clamped_q, ss_anim->current_mod, zero_ang, engine_frame_time * M_PI / 1.3f); vec4_copy(ss_anim->current_mod, clamped_q); SSBoneFrame_RotateBone(bf, ss_anim->current_mod, ss_anim->targeting_bone); } else { vec4_set_zero_angle(ss_anim->current_mod); } } }
void SSBoneFrame_TargetBoneToSlerp(struct ss_bone_frame_s *bf, struct ss_bone_tag_s *b_tag, float time) { b_tag->mod.current_slerp = 1.0f; if(b_tag->is_targeted) { float clamped_q[4], q[4], target_dir[3], target_local[3], bone_dir[3]; Mat4_vec3_mul_inv(target_local, bf->transform->M4x4, b_tag->mod.target_pos); if(b_tag->parent) { Mat4_vec3_mul_inv(target_local, b_tag->parent->current_transform, target_local); } vec3_sub(target_dir, target_local, b_tag->local_transform + 12); vec3_copy(bone_dir, b_tag->mod.bone_local_direction); vec4_GetQuaternionRotation(q, bone_dir, target_dir); if(q[3] < b_tag->mod.limit[3]) { vec4_clampw(q, b_tag->mod.limit[3]); } if(b_tag->is_axis_modded) { q[0] *= b_tag->mod.axis_mod[0]; q[1] *= b_tag->mod.axis_mod[1]; q[2] *= b_tag->mod.axis_mod[2]; q[3] = 1.0f - vec3_sqabs(q); q[3] = sqrtf(q[3]); } b_tag->mod.current_slerp = vec4_slerp_to(clamped_q, b_tag->mod.current_q, q, time * M_PI / 1.3f); vec4_copy(b_tag->mod.current_q, clamped_q); SSBoneFrame_RotateBone(bf, b_tag->mod.current_q, b_tag->index); } else if(b_tag->mod.current_q[3] < 1.0f) { if(b_tag->mod.current_q[3] < 0.99f) { float zero_ang[4] = {0.0f, 0.0f, 0.0f, 1.0f}; float clamped_q[4]; vec4_slerp_to(clamped_q, b_tag->mod.current_q, zero_ang, time * M_PI / 1.3f); vec4_copy(b_tag->mod.current_q, clamped_q); SSBoneFrame_RotateBone(bf, b_tag->mod.current_q, b_tag->index); } else { vec4_set_zero_angle(b_tag->mod.current_q); } } }