size_t dim[0];
};
-static inline __attribute__((always_inline)) void *array_new(
+// following constructor is geared towards being called from array_dupN()
+// which already has the strides available, so it doesn't calculate them
+static inline __attribute__((always_inline)) struct array *array_new(
int n_dims,
size_t *dim,
size_t *stride
return p;
}
-static inline __attribute__((always_inline)) void *array_new0(void) {
+static inline __attribute__((always_inline)) void array_free(
+ struct array *self
+) {
+ free(self);
+}
+
+// following are more optimized constructors for when number of dimensions
+// is known but strides are not known and must be calculated from dimensions
+static inline __attribute__((always_inline)) struct array *array_new0(void) {
struct array *p = aligned_alloc(
ALIGN,
(
return p;
}
-static inline __attribute__((always_inline)) void *array_new1(
+static inline __attribute__((always_inline)) struct array *array_new0_init(
+ const void *src
+) {
+ struct array *p = array_new0();
+ memcpy(p->data, src, p->stride[0]);
+ return p;
+}
+
+static inline __attribute__((always_inline)) struct array *array_new0_zero(void) {
+ struct array *p = array_new0();
+ memset(p->data, 0, p->stride[0]);
+ return p;
+}
+
+static inline __attribute__((always_inline)) struct array *array_new1(
size_t dim0
) {
struct array *p = aligned_alloc(
return p;
}
-static inline __attribute__((always_inline)) void *array_new2(
+static inline __attribute__((always_inline)) struct array *array_new1_init(
+ size_t dim0,
+ const void *src
+) {
+ struct array *p = array_new1(dim0);
+ memcpy(p->data, src, p->stride[0]);
+ return p;
+}
+
+static inline __attribute__((always_inline)) struct array *array_new1_zero(
+ size_t dim0
+) {
+ struct array *p = array_new1(dim0);
+ memset(p->data, 0, p->stride[0]);
+ return p;
+}
+
+static inline __attribute__((always_inline)) struct array *array_new2(
size_t dim0,
size_t dim1
) {
return p;
}
-static inline __attribute__((always_inline)) void *array_new3(
+static inline __attribute__((always_inline)) struct array *array_new2_init(
+ size_t dim0,
+ size_t dim1,
+ const void *src
+) {
+ struct array *p = array_new2(dim0, dim1);
+ memcpy(p->data, src, p->stride[0]);
+ return p;
+}
+
+static inline __attribute__((always_inline)) struct array *array_new2_zero(
+ size_t dim0,
+ size_t dim1
+) {
+ struct array *p = array_new2(dim0, dim1);
+ memset(p->data, 0, p->stride[0]);
+ return p;
+}
+
+static inline __attribute__((always_inline)) struct array *array_new3(
size_t dim0,
size_t dim1,
size_t dim2
return p;
}
-static inline __attribute__((always_inline)) void *array_new4(
+static inline __attribute__((always_inline)) struct array *array_new3_init(
+ size_t dim0,
+ size_t dim1,
+ size_t dim2,
+ const void *src
+) {
+ struct array *p = array_new3(dim0, dim1, dim2);
+ memcpy(p->data, src, p->stride[0]);
+ return p;
+}
+
+static inline __attribute__((always_inline)) struct array *array_new3_zero(
+ size_t dim0,
+ size_t dim1,
+ size_t dim2
+) {
+ struct array *p = array_new3(dim0, dim1, dim2);
+ memset(p->data, 0, p->stride[0]);
+ return p;
+}
+
+static inline __attribute__((always_inline)) struct array *array_new4(
size_t dim0,
size_t dim1,
size_t dim2,
return p;
}
-static inline __attribute__((always_inline)) void array_free(
- struct array *self
+static inline __attribute__((always_inline)) struct array *array_new4_init(
+ size_t dim0,
+ size_t dim1,
+ size_t dim2,
+ size_t dim3,
+ const void *src
) {
- free(self);
+ struct array *p = array_new4(dim0, dim1, dim2, dim3);
+ memcpy(p->data, src, p->stride[0]);
+ return p;
+}
+
+static inline __attribute__((always_inline)) struct array *array_new4_zero(
+ size_t dim0,
+ size_t dim1,
+ size_t dim2,
+ size_t dim3
+) {
+ struct array *p = array_new4(dim0, dim1, dim2, dim3);
+ memset(p->data, 0, p->stride[0]);
+ return p;
}
static inline __attribute__((always_inline)) void *array_index0(
static inline __attribute__((always_inline)) void array_set1(
struct array *self,
- const void *src,
- size_t i0
+ size_t i0,
+ const void *src
) {
memcpy(array_index1(self, i0), src, self->stride[1]);
}
static inline __attribute__((always_inline)) void array_set2(
struct array *self,
- const void *src,
size_t i0,
- size_t i1
+ size_t i1,
+ const void *src
) {
memcpy(array_index2(self, i0, i1), src, self->stride[2]);
}
static inline __attribute__((always_inline)) void array_set3(
struct array *self,
- const void *src,
size_t i0,
size_t i1,
- size_t i2
+ size_t i2,
+ const void *src
) {
memcpy(array_index3(self, i0, i1, i2), src, self->stride[3]);
}
static inline __attribute__((always_inline)) void array_set4(
struct array *self,
- const void *src,
size_t i0,
size_t i1,
size_t i2,
- size_t i3
+ size_t i3,
+ const void *src
) {
memcpy(array_index4(self, i0, i1, i2, i3), src, self->stride[4]);
}
array_get2(B, &b, k, j);
c += a * b;
}
- array_set2(C, &c, i, j);
+ array_set2(C, i, j, &c);
}
}
void mul_mat34_mat44(struct array *A, struct array *B, struct array *C) {
array_get2(B, &b, k, j);
c += a * b;
}
- array_set2(C, &c, i, j);
+ array_set2(C, i, j, &c);
}
}
void mul_mat44_mat44(struct array *A, struct array *B, struct array *C) {
array_get2(B, &b, k, j);
c += a * b;
}
- array_set2(C, &c, i, j);
+ array_set2(C, i, j, &c);
}
}
void mul_mat34_vec4(struct array *A, struct array *B, struct array *C) {
array_get1(B, &b, j);
c += a * b;
}
- array_set1(C, &c, i);
+ array_set1(C, i, &c);
}
}
void rotate(const float (*v)[4], struct array *transform) {
- struct array *t0 = array_new3(4, 4, sizeof(float));
- array_set0(t0, v);
+ struct array *t0 = array_new3_init(4, 4, sizeof(float), v);
struct array *t1 = array_new3(4, 4, sizeof(float));
mul_mat44_mat44(t0, transform, t1);
array_set0(transform, array_index0(t1));
}
// device
- struct array *device_transform = array_new3(3, 3, sizeof(float));
- {
- float v[3][3] = {
+ struct array *device_transform = array_new3_init(
+ 3,
+ 3,
+ sizeof(float),
+ (float[3][3]){
{WINDOW_WIDTH, 0.f, .5f * WINDOW_WIDTH},
{0.f, WINDOW_WIDTH, .5f * WINDOW_HEIGHT},
{0.f, 0.f, 1.f},
- };
- array_set0(device_transform, v);
- }
+ }
+ );
printf("device_transform\n");
print_mat330(device_transform);
printf("\n");
// perspective
- struct array *perspective_transform = array_new3(3, 4, sizeof(float));
- {
- float v[3][4] = {
+ struct array *perspective_transform = array_new3_init(
+ 3,
+ 4,
+ sizeof(float),
+ (float[3][4]){
{1.f, 0.f, 0.f, 0.f},
{0.f, 0.f, 1.f, 0.f},
{0.f, 1.f, 0.f, 0.f},
- };
- array_set0(perspective_transform, v);
- }
+ }
+ );
printf("perspective_transform\n");
print_mat340(perspective_transform);
printf("\n");
// camera
- struct array *camera_rotate = array_new3(4, 4, sizeof(float));
- {
- float v[4][4] = {
+ struct array *camera_rotate = array_new3_init(
+ 4,
+ 4,
+ sizeof(float),
+ (float[4][4]){
{1.f, 0.f, 0.f, 0.f},
{0.f, 1.f, 0.f, 0.f},
{0.f, 0.f, 1.f, 0.f},
{0.f, 0.f, 0.f, 1.f}
- };
- array_set0(camera_rotate, v);
- }
+ }
+ );
printf("camera_rotate\n");
print_mat440(camera_rotate);
printf("\n");
- struct array *camera_translate = array_new3(4, 4, sizeof(float));
- {
- float v[4][4] = {
+ struct array *camera_translate = array_new3_init(
+ 4,
+ 4,
+ sizeof(float),
+ (float[4][4]){
{1.f, 0.f, 0.f, 0.f},
{0.f, 1.f, 0.f, 10.f},
{0.f, 0.f, 1.f, 0.f},
{0.f, 0.f, 0.f, 1.f}
- };
- array_set0(camera_translate, v);
- }
+ }
+ );
printf("camera_translate\n");
print_mat440(camera_translate);
printf("\n");
for (int j = 0; j < 2; ++j)
for (int k = 0; k < 2; ++k) {
float v[4] = {i * 2 - 1, j * 2 - 1, k * 2 - 1, 1.f};
- array_set1(model_vertices, v, i * 4 + j * 2 + k);
+ array_set1(model_vertices, i * 4 + j * 2 + k, v);
}
printf("model_vertices\n");
for (int i = 0; i < 8; ++i) {
//{7, 3}, // 1, 1, 1 -> 0, 1, 1
};
- struct array *model_rotate = array_new3(4, 4, sizeof(float));
- {
- float v[4][4] = {
+ struct array *model_rotate = array_new3_init(
+ 4,
+ 4,
+ sizeof(float),
+ (float[4][4]){
{1.f, 0.f, 0.f, 0.f},
{0.f, 1.f, 0.f, 0.f},
{0.f, 0.f, 1.f, 0.f},
{0.f, 0.f, 0.f, 1.f}
- };
- array_set0(model_rotate, v);
- }
+ }
+ );
printf("model_rotate\n");
print_mat440(model_rotate);
printf("\n");
- struct array *model_translate = array_new3(4, 4, sizeof(float));
- {
- float v[4][4] = {
+ struct array *model_translate = array_new3_init(
+ 4,
+ 4,
+ sizeof(float),
+ (float[4][4]){
{1.f, 0.f, 0.f, 0.f},
{0.f, 1.f, 0.f, 0.f},
{0.f, 0.f, 1.f, 0.f},
{0.f, 0.f, 0.f, 1.f}
- };
- array_set0(model_translate, v);
- }
+ }
+ );
printf("model_translate\n");
print_mat440(model_translate);
printf("\n");
array_get2(model_vertices, &b, i, k);
c += a * b;
}
- array_set2(p, &c, i, j);
+ array_set2(p, i, j, &c);
}
// unproject
if (v[2] >= EPSILON) {
v[0] /= v[2];
v[1] /= v[2];
- array_set1(p, v, i);
+ array_set1(p, i, v);
}
}