Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add determinant, laplace and cross products to math_vector.c3 #2040

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion lib/std/collections/priorityqueue.c3
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct PrivatePriorityQueue (Printable)
List{Type} heap;
}

fn PrivatePriorityQueue* PrivatePriorityQueue.init(&self, Allocator allocator, usz initial_capacity = 16, ) @inline
fn PrivatePriorityQueue* PrivatePriorityQueue.init(&self, Allocator allocator, usz initial_capacity = 16) @inline
{
self.heap.init(allocator, initial_capacity);
return self;
Expand Down
33 changes: 26 additions & 7 deletions lib/std/math/math_vector.c3
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,32 @@ fn double[<3>] double[<3>].unproject(self, Matrix4 projection, Matrix4 view) =>
fn void ortho_normalize(float[<3>]* v1, float[<3>]* v2) => ortho_normalize3(v1, v2);
fn void ortho_normalized(double[<3>]* v1, double[<3>]* v2) => ortho_normalize3(v1, v2);

/* determinants */
macro float[<*>].determinant2(self, float[<*>] b) => determinant2(self,b);
macro float[<*>].determinant3(self, float[<*>] b, float[<*>] c) => determinant3(self, b, c);
macro float[<*>].determinant4(self, float[<*>] b, float[<*>] c, float[<*>] d) => determinant4(self, b, c, d);
/* laplace */
macro float[<*>].laplace2(self) => laplace2(self);
macro float[<*>].laplace3(self, float[<*>] b) => laplace3(self, b);
macro float[<*>].laplace4(self, float[<*>] b, float[<*>] c) => laplace4(self, b, c);
/* cross[2,3,4] products */
macro float[<*>].cross2(self, uint winding = 0x901) => cross2(self, winding);
macro float[<*>].cross3(self, float[<*>] other) => cross3(self, other);
macro float[<*>].cross4(self, float[<*>] b, float[<*>] c) => cross4(self, b, c);

macro determinant2(a, b) => ({ 1,-1 } * a.xy * laplace2(b )).sum();
macro determinant3(a, b, c) => ({ 1,-1, 1 } * a.xyz * laplace3(b.xyz,c.xyz )).sum();
macro determinant4(a, b, c, d) => ({ 1,-1, 1, -1 } * a.xyzw * laplace4(b.xyzw,c.xyzw,d.xyzw)).sum();

macro laplace2(a) => a.yx;
macro laplace3(a, b) => ($typeof(a)){ determinant2(a.yz,b.yz), determinant2(a.xz,b.xz), determinant2(a.xy,b.xy) };
macro laplace4(a, b, c) => ($typeof(a)){ determinant3(a.yzw,b.yzw,c.yzw), determinant3(a.xzw,b.xzw,c.xzw), determinant3(a.xyw,b.xyw,c.xyw), determinant3(a.xyz,b.xyz,c.xyz) };

/* use GL_CW=0x900/GL_CCW=0x901 or 0/1 as winding */
macro cross2(a, uint winding = 0x901) => { (winding % 2 == 0 ? -1 : 1), 1 } * laplace2(a);
macro cross3(a, b) => a.yzx * b.zxy - a.zxy * b.yzx;
macro cross4(a, b, c) => {-1, 1, -1, 1} * laplace4(a.xyzw,b.xyzw,c.xyzw);

macro towards(v, target, max_distance) @private
{
var delta = target - v;
Expand Down Expand Up @@ -102,13 +128,6 @@ macro perpendicular3(v) @private
return cross3(v, cardinal_axis);
}

macro cross3(v1, v2) @private
{
var a = v1.yzx * v2.zxy;
var b = v1.zxy * v2.yzx;
return a - b;
}

macro transform2(v, mat) @private
{
return $typeof(v) {
Expand Down
6 changes: 1 addition & 5 deletions src/compiler/parse_global.c
Original file line number Diff line number Diff line change
Expand Up @@ -1353,11 +1353,7 @@ bool parse_parameters(ParseContext *c, Decl ***params_ref, Variadic *variadic, i
// We might have Foo...
if (ellipsis)
{
if (!variadic)
{
PRINT_ERROR_HERE("Variadic arguments are not allowed.");
return false;
}
if (!variadic) RETURN_PRINT_ERROR_HERE("Variadic arguments are not allowed.");
if (var_arg_found)
{
print_error_at(extend_span_with_token(type->span, c->prev_span), "Only a single variadic parameter is allowed.");
Expand Down
13 changes: 7 additions & 6 deletions src/compiler/sema_decls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1229,12 +1229,13 @@ static inline bool sema_analyse_signature(SemaContext *context, Signature *sig,
if (!sema_resolve_type_info(context, type_info,
is_macro ? RESOLVE_TYPE_ALLOW_INFER
: RESOLVE_TYPE_DEFAULT)) return decl_poison(param);
param->type = type_info->type;
}
if (type_info && param->var.no_alias && !type_is_pointer(param->type) && type_flatten(param->type)->type_kind != TYPE_SLICE)
{
SEMA_ERROR(param, "The parameter was set to @noalias, but it was neither a slice nor a pointer. You need to either remove '@noalias' or use pointer/slice type.");
return decl_poison(param);

Type *type = param->type = type_info->type;
if (param->var.no_alias && !type_is_pointer(type) && type_flatten(type)->type_kind != TYPE_SLICE)
{
SEMA_ERROR(param, "The parameter was set to @noalias, but it was neither a slice nor a pointer. You need to either remove '@noalias' or use pointer/slice type.");
return decl_poison(param);
}
}
switch (var_kind)
{
Expand Down
18 changes: 17 additions & 1 deletion test/unit/stdlib/math/math_vector.c3
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,20 @@ fn void test_type_consistency() @test
double[<3>] v3d = { 1.0, 2.0, 3.0 };
$assert @typeis(v3f.cross(v3f)[0], float);
$assert @typeis(v3d.cross(v3d)[0], double);
}
}

fn void test_vec_cross() @test
{
float[<4>] u = { 1,0,0,0 };
float[<4>] v = { 0,1,0,0 };
float[<4>] w = { 0,0,1,0 };

float[<4>] x = vector::cross4(u,v,w);
float[<3>] y = vector::cross3(u,v);
float[<2>] z = vector::cross2(u);

assert(x == {-0, 0,-0, 1 });
assert(y == { 0, 0, 1 });
assert(z == { 0, 1 });
}

Loading