Struct rin::graphics::Node [−][src]
pub struct Node { /* fields omitted */ }
Position + Orientation + Scale of an object
Represents a model matrix decomposed into it’s components and caches this values so the matrix only is recalculated when any of the original values changes
Also calculates a global matrix from an optional parent
The update of the matrices happens whenever any of the update_* functions is called so don’t forget to call one of them before using the matrices after a change
A node that has just been created contains the correct updated matrices
Implementations
impl Node
[src]
impl Node
[src]pub fn new(
pos: Point<f32, U3>,
orientation: Unit<Quaternion<f32>>,
scale: Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
) -> Node
[src]
pos: Point<f32, U3>,
orientation: Unit<Quaternion<f32>>,
scale: Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
) -> Node
pub fn from_position(pos: Point<f32, U3>) -> Node
[src]
pub fn with_parent(
parent: &Node,
pos: Point<f32, U3>,
orientation: Unit<Quaternion<f32>>,
scale: Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
) -> Node
[src]
parent: &Node,
pos: Point<f32, U3>,
orientation: Unit<Quaternion<f32>>,
scale: Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
) -> Node
pub fn identity() -> Node
[src]
A node that applies no transformation
pub fn has_changed(&self) -> bool
[src]
pub fn reset_changed(&mut self)
[src]
pub fn identity_with_parent(parent: &Node) -> Node
[src]
A node that applies no transformation but the global transformation contains the parent’s
pub fn new_look_at(
eye: Point<f32, U3>,
at: Point<f32, U3>,
up: Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
) -> Result<Node, Error>
[src]
eye: Point<f32, U3>,
at: Point<f32, U3>,
up: Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
) -> Result<Node, Error>
A node that orients an object to look at a certain target
- eye: position of the object
- at: where the object will be looking at
- up: up vector
Returns an error if the look at direction and the up vector are parallel
pub fn with_preparent(
parent_inv: Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>,
pos: Point<f32, U3>,
orientation: Unit<Quaternion<f32>>,
scale: Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
) -> Node
[src]
parent_inv: Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>,
pos: Point<f32, U3>,
orientation: Unit<Quaternion<f32>>,
scale: Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
) -> Node
New node that stores the inverse of the current parent
When parenting a node at a certain position, orientation and scale allows for those to be absolute instead of relative to the parent.
This version of the method takes a Mat4 as preparent inverse global transformation
pub fn with_preparent_node(
preparent: &Node,
pos: Point<f32, U3>,
orientation: Unit<Quaternion<f32>>,
scale: Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
) -> Node
[src]
preparent: &Node,
pos: Point<f32, U3>,
orientation: Unit<Quaternion<f32>>,
scale: Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
) -> Node
New node that stores the inverse of the current parent
When parenting a node at a certain position, orientation and scale allows for those to be absolute instead of relative to the parent.
This version of the method takes another node as preparent global transformation
pub fn identity_with_preparent(
parent_inv: Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
) -> Node
[src]
parent_inv: Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
) -> Node
New node that stores the inverse of the current parent and applies no transformation itself
When parenting a node at a certain position, orientation and scale allows for those to be absolute instead of relative to the parent.
This version of the method takes another node as preparent global transformation
pub fn identity_with_preparent_node(preparent: &Node) -> Node
[src]
New node that stores the inverse of the current parent and applies no transformation itself
When parenting a node at a certain position, orientation and scale allows for those to be absolute instead of relative to the parent.
This version of the method takes a Mat4 as preparent inverse global transformation
pub fn clone_with_preparent(&self, preparent: &Node) -> Node
[src]
Clones this node but applies a preparent transformation
Allows to parent this node with it’s current position, orientation and scale as absolute instead of relative to the parent.
pub fn set_position(&mut self, pos: Point<f32, U3>)
[src]
Sets the local position of this node
pub fn position(&self) -> Point<f32, U3>
[src]
Returns the local position of this node
pub fn preparent(
&self
) -> Option<Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>>
[src]
&self
) -> Option<Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>>
Returns the initial parent inverse transformation if there’s one
pub fn set_angle_axis(
&mut self,
angle: Rad<f32>,
axis: &Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
)
[src]
&mut self,
angle: Rad<f32>,
axis: &Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
)
Sets the orientation for this node from an angle and axis of rotation
pub fn set_orientation(&mut self, q: Unit<Quaternion<f32>>)
[src]
Sets the orientation for this node from a quaternion
pub fn orientation(&self) -> Unit<Quaternion<f32>>
[src]
Returns the orientation of this node as a quaternion which is how it’s stored internally
pub fn rotation(&self) -> Rotation<f32, U3>
[src]
Returns the orientation of this node as a Rotation3.
This method converts the internal quaternion into a Rotation3
pub fn look_at(
&mut self,
at: &Point<f32, U3>,
up: &Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
) -> Result<(), Error>
[src]
&mut self,
at: &Point<f32, U3>,
up: &Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
) -> Result<(), Error>
Changes the orientation of the node to look at the passed position using the up vector
Returns an error if the look at direction and the up vector are parallel
pub fn face_towards(
&mut self,
dir: &Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>,
up: &Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
) -> Result<(), Error>
[src]
&mut self,
dir: &Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>,
up: &Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
) -> Result<(), Error>
Changes the orientation of the node to look at the passed direction using the up vector
Returns an error if the look at direction and the up vector are parallel
pub fn look_at_node<N>(
&mut self,
node: &N,
up: &Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
) -> Result<(), Error> where
N: NodeRef,
[src]
&mut self,
node: &N,
up: &Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
) -> Result<(), Error> where
N: NodeRef,
Changes the orientation of the node to look at the passed node global position using the up vector
Returns an error if the look at direction and the up vector are parallel
pub fn rotate(
&mut self,
angle: Rad<f32>,
axis: &Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
)
[src]
&mut self,
angle: Rad<f32>,
axis: &Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
)
Rotate this note a certain angle around the axis of rotation
pub fn append_orientation(&mut self, rot: &Unit<Quaternion<f32>>)
[src]
Append the passed quaternion to the current local orientation
pub fn translate(
&mut self,
t: &Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
)
[src]
&mut self,
t: &Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
)
Append a translation to the current local position
pub fn scale(
&self
) -> Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
[src]
&self
) -> Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
Returns the current local scale
pub fn set_scale(
&mut self,
s: Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
)
[src]
&mut self,
s: Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
)
Sets the local scale
pub fn local_x_axis(
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
[src]
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
The node orientation x axis
pub fn local_y_axis(
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
[src]
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
The node orientation y axis
pub fn local_z_axis(
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
[src]
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
The node orientation z axis
pub fn global_x_axis(
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
[src]
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
The node orientation x axis
pub fn global_y_axis(
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
[src]
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
The node orientation y axis
pub fn global_z_axis(
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
[src]
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
The node orientation z axis
pub fn tilt(&mut self, angle: Rad<f32>)
[src]
rotate this node around it’s local x axis
pub fn pan(&mut self, angle: Rad<f32>)
[src]
rotate this node around it’s local y axis
pub fn roll(&mut self, angle: Rad<f32>)
[src]
rotate this node around it’s local z axis
pub fn local_transformation(
&self
) -> Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
[src]
&self
) -> Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
Local transformation matrix
pub fn global_transformation(
&self
) -> Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
[src]
&self
) -> Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
Global transformation matrix
pub fn global_position(&self) -> Point<f32, U3>
[src]
Global position of this node
pub fn global_orientation(&self) -> Unit<Quaternion<f32>>
[src]
Global orientation of this node
pub fn global_scale(
&self
) -> Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
[src]
&self
) -> Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
Global scale of this node
pub fn inv_local_transformation(
&self
) -> Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
[src]
&self
) -> Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
Inverse local transformation of this node
This is cacheed internally and uses the fastest version posible to calculate
the inverse so it’s usually faster than calling local_transformation().try_inverse()
pub fn inv_global_transformation(
&self
) -> Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
[src]
&self
) -> Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
Inverse global transformation of this node
This is cacheed internally and uses the fastest version posible to calculate
the inverse so it’s usually faster than calling global_transformation().try_inverse()
pub fn update_with_parent(&mut self, parent: Option<&Node>) -> bool
[src]
Updates the internal matrices including the glonal matrices using the optional parent passed as argument
pub fn update_with_parent_parts(
&mut self,
parent_loc: Option<&Node>,
parent_orientation: Option<&Node>,
parent_scale: Option<&Node>
) -> bool
[src]
&mut self,
parent_loc: Option<&Node>,
parent_orientation: Option<&Node>,
parent_scale: Option<&Node>
) -> bool
Updates the internal matrices including the glonal matrices using the optional parent passed as argument and flags
Trait Implementations
impl<'a> DebugParameter for Node
[src]
impl<'a> DebugParameter for Node
[src]pub fn debug<S>(
&self,
serializer: S
) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error> where
S: Serializer,
[src]
&self,
serializer: S
) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error> where
S: Serializer,
impl<'de> Deserialize<'de> for Node
[src]
impl<'de> Deserialize<'de> for Node
[src]pub fn deserialize<__D>(
__deserializer: __D
) -> Result<Node, <__D as Deserializer<'de>>::Error> where
__D: Deserializer<'de>,
[src]
__deserializer: __D
) -> Result<Node, <__D as Deserializer<'de>>::Error> where
__D: Deserializer<'de>,
impl NodeMut for Node
[src]
impl NodeMut for Node
[src]pub fn node_mut(&mut self) -> &mut Node
[src]
pub fn update_with_parent(&mut self, parent: Option<&Node>) -> bool
[src]
pub fn update_with_parent_parts(
&mut self,
parent_loc: Option<&Node>,
parent_orientation: Option<&Node>,
parent_scale: Option<&Node>
) -> bool
[src]
&mut self,
parent_loc: Option<&Node>,
parent_orientation: Option<&Node>,
parent_scale: Option<&Node>
) -> bool
pub fn look_at(
&mut self,
at: &Point<f32, U3>,
up: &Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
) -> Result<(), Error>
[src]
&mut self,
at: &Point<f32, U3>,
up: &Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
) -> Result<(), Error>
pub fn rotate(
&mut self,
angle: Rad<f32>,
axis: &Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
)
[src]
&mut self,
angle: Rad<f32>,
axis: &Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
)
pub fn append_orientation(&mut self, rot: &Unit<Quaternion<f32>>)
[src]
pub fn tilt(&mut self, angle: Rad<f32>)
[src]
pub fn pan(&mut self, angle: Rad<f32>)
[src]
pub fn roll(&mut self, angle: Rad<f32>)
[src]
pub fn set_scale(
&mut self,
s: Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
)
[src]
&mut self,
s: Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
)
pub fn translate(
&mut self,
t: &Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
)
[src]
&mut self,
t: &Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
)
pub fn set_position(&mut self, pos: Point<f32, U3>)
[src]
pub fn set_angle_axis(
&mut self,
angle: Rad<f32>,
axis: &Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
)
[src]
&mut self,
angle: Rad<f32>,
axis: &Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
)
pub fn set_orientation(&mut self, q: Unit<Quaternion<f32>>)
[src]
impl NodeRef for Node
[src]
impl NodeRef for Node
[src]pub fn node(&self) -> &Node
[src]
pub fn position(&self) -> Point<f32, U3>
[src]
pub fn orientation(&self) -> Unit<Quaternion<f32>>
[src]
pub fn rotation(&self) -> Rotation<f32, U3>
[src]
pub fn scale(
&self
) -> Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
[src]
&self
) -> Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
pub fn local_x_axis(
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
[src]
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
pub fn local_y_axis(
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
[src]
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
pub fn local_z_axis(
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
[src]
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
pub fn global_x_axis(
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
[src]
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
pub fn global_y_axis(
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
[src]
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
pub fn global_z_axis(
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
[src]
&self
) -> Unit<Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>>
pub fn local_transformation(
&self
) -> Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
[src]
&self
) -> Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
pub fn global_transformation(
&self
) -> Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
[src]
&self
) -> Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
pub fn global_position(&self) -> Point<f32, U3>
[src]
pub fn global_orientation(&self) -> Unit<Quaternion<f32>>
[src]
pub fn global_scale(
&self
) -> Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
[src]
&self
) -> Matrix<f32, U3, U1, <DefaultAllocator as Allocator<f32, U3, U1>>::Buffer>
pub fn inv_local_transformation(
&self
) -> Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
[src]
&self
) -> Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
pub fn inv_global_transformation(
&self
) -> Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
[src]
&self
) -> Matrix<f32, U4, U4, <DefaultAllocator as Allocator<f32, U4, U4>>::Buffer>
impl Serialize for Node
[src]
impl Serialize for Node
[src]pub fn serialize<__S>(
&self,
__serializer: __S
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error> where
__S: Serializer,
[src]
&self,
__serializer: __S
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error> where
__S: Serializer,
impl Copy for Node
[src]
Auto Trait Implementations
impl RefUnwindSafe for Node
impl Send for Node
impl Sync for Node
impl Unpin for Node
impl UnwindSafe for Node
Blanket Implementations
impl<T> DowncastSync for T where
T: Any + Send + Sync,
[src]
impl<T> DowncastSync for T where
T: Any + Send + Sync,
[src]impl<T> Serialize for T where
T: Serialize + ?Sized,
[src]
impl<T> Serialize for T where
T: Serialize + ?Sized,
[src]pub fn erased_serialize(
&self,
serializer: &mut dyn Serializer
) -> Result<Ok, Error>
[src]
&self,
serializer: &mut dyn Serializer
) -> Result<Ok, Error>
impl<SS, SP> SupersetOf<SS> for SP where
SS: SubsetOf<SP>,
[src]
impl<SS, SP> SupersetOf<SS> for SP where
SS: SubsetOf<SP>,
[src]pub fn to_subset(&self) -> Option<SS>
[src]
pub fn is_in_subset(&self) -> bool
[src]
pub fn to_subset_unchecked(&self) -> SS
[src]
pub fn from_subset(element: &SS) -> SP
[src]
impl<SS, SP> SupersetOf<SS> for SP where
SS: SubsetOf<SP>,
[src]
impl<SS, SP> SupersetOf<SS> for SP where
SS: SubsetOf<SP>,
[src]pub fn to_subset(&self) -> Option<SS>
[src]
pub fn is_in_subset(&self) -> bool
[src]
pub fn to_subset_unchecked(&self) -> SS
[src]
pub fn from_subset(element: &SS) -> SP
[src]
impl<C> ComponentSend for C where
C: Component + Send,
[src]
C: Component + Send,
impl<C> ComponentThreadLocal for C where
C: Component,
[src]
C: Component,
impl<T> DeserializeOwned for T where
T: for<'de> Deserialize<'de>,
[src]
T: for<'de> Deserialize<'de>,
impl<T> Slottable for T where
T: Copy,
[src]
T: Copy,