/// <summary> /// Constructor (Named) - /// </summary> /// <param name="arc_visitor"></param> /// <param name="angular_position"></param> /// <param name="extrusion"></param> /// <param name="transformation"></param> /// <returns></returns> public static ShapeVisitor geometry_visitor(ArcVisitor arc_visitor, float angular_position, float extrusion, Transform transformation) { ShapeVisitor result = new ShapeVisitor(arc_visitor, extrusion, transformation); result.set_position(angular_position); return(result); }
public static optional <BlockCollision> block_collision(CollisionObserver observer, Arc arc, PlanetariaCollider collider, PlanetariaTransform transformation, PlanetariaRigidbody rigidbody) { optional <ArcVisitor> arc_visitor = collider.shape.arc_visitor(arc); if (!arc_visitor.exists) { Debug.LogError("This should never happen"); return(new optional <BlockCollision>()); } Quaternion block_to_world = collider.gameObject.internal_game_object.transform.rotation; Quaternion world_to_block = Quaternion.Inverse(block_to_world); Vector3 last_position = world_to_block * rigidbody.get_previous_position(); Vector3 current_position = world_to_block * rigidbody.get_position(); float extrusion = transformation.scale / 2; optional <Vector3> intersection_point = PlanetariaIntersection.arc_path_intersection(arc, last_position, current_position, extrusion); if (!intersection_point.exists) // theoretically only happens with moving objects for discrete collision checks { // these functions are general inverses of one another, but also serve to constrain/normalize the position to the arc path. float intersection_angle = arc.position_to_angle(current_position); if (Mathf.Abs(intersection_angle) <= arc.angle() / 2) // if the intersection is valid { intersection_point = arc.position(intersection_angle); // set the collision to the extruded collision point } } if (!intersection_point.exists) { Debug.LogError("Research why this happened."); return(new optional <BlockCollision>()); } BlockCollision result = new BlockCollision(); float angle = arc.position_to_angle(intersection_point.data); result.geometry_visitor = ShapeVisitor.geometry_visitor(arc_visitor.data, angle, extrusion, collider.gameObject.internal_game_object.transform); intersection_point.data = block_to_world * intersection_point.data; result.distance = Vector3.Angle(intersection_point.data, rigidbody.get_previous_position()) * Mathf.Deg2Rad; result.overshoot = Vector3.Angle(intersection_point.data, rigidbody.get_position()) * Mathf.Deg2Rad; result.observer = observer; result.self = observer.collider(); result.other = collider; PlanetariaPhysicMaterial self = result.self.material; PlanetariaPhysicMaterial other = result.other.material; result.elasticity = PlanetariaPhysics.blend( self.elasticity, self.elasticity_combine, other.elasticity, other.elasticity_combine); result.friction = PlanetariaPhysics.blend( self.friction, self.friction_combine, other.friction, other.friction_combine); result.magnetism = -(self.magnetism - other.magnetism * self.induced_magnetism_multiplier) * (other.magnetism - self.magnetism * other.induced_magnetism_multiplier); return(result); }