Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion zap/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ impl<'src> Ty<'src> {
Self::Color3 => Some(NumTy::U8.size() * 3),
Self::Vector3 => Some(NumTy::F32.size() * 3),
Self::AlignedCFrame => Some(NumTy::U8.size() + NumTy::F32.size() * 3),
Self::CFrame => Some(NumTy::F32.size() * 12),
Self::CFrame => Some(NumTy::F32.size() * 6),
Self::Boolean => Some(1),
Self::Opt(ty) => ty.max_size(config, recursed).map(|size| size + 1),
Self::Str(len) => len.max().map(|len| len as usize),
Expand Down
39 changes: 32 additions & 7 deletions zap/src/irgen/des.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,16 +281,41 @@ impl Des {
}
Ty::CFrame => {
self.push_local("pos", Some(self.readvector3()));
self.push_local("vX", Some(self.readvector3()));
self.push_local("vY", Some(self.readvector3()));
self.push_local("vZ", Some(self.readvector3()));
self.push_local("axisangle", Some(self.readvector3()));
self.push_local(
"angle",
Some(Expr::Var(Box::new(Var::NameIndex(
Box::new("axisangle".into()),
"Magnitude".into(),
)))),
);
Comment thread
Tazmondo marked this conversation as resolved.
Outdated

// We don't need to convert the axis back to a unit vector as the constructor does that for us
// The angle is the magnitude of the axis vector
// If the magnitude is 0, there is no rotation, so just make a cframe at the right position.
// Trying to use fromAxisAngle in this situation gives NAN which is not ideal, so the and/or clause is required.

// value = angle ~= 0 and CFrame.fromAxisAngle(axisangle, angle) + pos or CFrame.new(pos)

self.push_assign(
into,
Expr::Call(
Box::new(Var::from("CFrame").nindex("fromMatrix")),
None,
vec!["pos".into(), "vX".into(), "vY".into(), "vZ".into()],
Expr::Or(
Box::new(Expr::And(
Box::new(Expr::Neq(Box::new("angle".into()), Box::new("0".into()))),
Box::new(Expr::Add(
Box::new(Expr::Call(
Box::new(Var::from("CFrame").nindex("fromAxisAngle")),
None,
vec!["axisangle".into(), "angle".into()],
)),
Box::new("pos".into()),
)),
)),
Box::new(Expr::Call(
Box::new(Var::from("CFrame").nindex("new")),
None,
vec!["pos".into()],
)),
Comment thread
Tazmondo marked this conversation as resolved.
Outdated
),
);
}
Expand Down
1 change: 1 addition & 0 deletions zap/src/irgen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ pub trait Gen {
#[derive(Debug, Clone)]
pub enum Stmt {
Local(&'static str, Option<Expr>),
LocalTuple(Vec<&'static str>, Option<Expr>),
Assign(Var, Expr),
Error(String),
Assert(Expr, Option<String>),
Expand Down
17 changes: 14 additions & 3 deletions zap/src/irgen/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,21 @@ impl Ser {
}

Ty::CFrame => {
// local axis, angle = Value:ToAxisAngle()
self.push_stmt(Stmt::LocalTuple(
vec!["axis", "angle"],
Some(Expr::Call(from.clone().into(), Some("ToAxisAngle".into()), vec![])),
));

// axis = axis * angle
// store the angle into the axis, as it is a unit vector, so the magnitude can be used to encode a number
self.push_stmt(Stmt::Assign(
Var::Name("axis".into()),
Expr::Mul(Box::new("axis".into()), Box::new("angle".into())),
));

self.push_ty(&Ty::Vector3, from.clone().nindex("Position"));
self.push_ty(&Ty::Vector3, from.clone().nindex("XVector"));
self.push_ty(&Ty::Vector3, from.clone().nindex("YVector"));
self.push_ty(&Ty::Vector3, from.clone().nindex("ZVector"));
self.push_ty(&Ty::Vector3, "axis".into());
}

Ty::Boolean => self.push_writeu8(from_expr.and(1.0.into()).or(0.0.into())),
Expand Down
16 changes: 16 additions & 0 deletions zap/src/output/luau/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ pub trait Output {
self.push_line(&format!("local {name}"));
}
}
Stmt::LocalTuple(var, expr) => {
let mut items = String::new();

for (i, exp) in var.iter().enumerate() {
if i != 0 {
items.push_str(", ");
}
items.push_str(exp)
}
Comment thread
Tazmondo marked this conversation as resolved.
Outdated

if let Some(expr) = expr {
self.push_line(&format!("local {items} = {expr}"));
} else {
self.push_line(&format!("local {items}"));
}
}

Stmt::Assign(var, expr) => self.push_line(&format!("{var} = {expr}")),
Stmt::Error(msg) => self.push_line(&format!("error(\"{msg}\")")),
Expand Down