~jfpacker/pyeigen/bugfixes-0.1

« back to all changes in this revision

Viewing changes to source/matrix4f.cpp

  • Committer: Jussi Lepistö
  • Date: 2010-03-20 00:16:13 UTC
  • Revision ID: jussi.lepisto@iki.fi-20100320001613-f08k4wgogq8p7ogf
- Directory structure reorganization
- Matrix inverse & transpose
- Class methods for creating matrices and vectors
- Matrix * vector multiply
- Fix repr for matrix classes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2010 Jussi Lepisto
2
 
 
3
 
#include "matrix4f.h"
4
 
 
5
 
#include <Eigen/Array>
6
 
#include <Eigen/Geometry>
7
 
 
8
 
#include "macros.h"
9
 
#include "matrix2f.h"
10
 
#include "matrix3f.h"
11
 
#include "vector4f.h"
12
 
 
13
 
// Structures
14
 
PyGetSetDef Matrix4f_getset[] = {
15
 
        {NULL}
16
 
};
17
 
 
18
 
PyMethodDef Matrix4f_methods[] = {
19
 
        {"set",                         (PyCFunction)Matrix4f_set,                      METH_VARARGS,
20
 
         ""},
21
 
        {"set_zero",            (PyCFunction)Matrix4f_set_zero,         METH_NOARGS,
22
 
         ""},
23
 
        {"set_ones",            (PyCFunction)Matrix4f_set_ones,         METH_NOARGS,
24
 
         ""},
25
 
        {"set_identity",        (PyCFunction)Matrix4f_set_identity,     METH_NOARGS,
26
 
         ""},
27
 
        {"set_constant",        (PyCFunction)Matrix4f_set_constant,     METH_VARARGS,
28
 
         ""},
29
 
        {"set_random",          (PyCFunction)Matrix4f_set_random,       METH_NOARGS,
30
 
         ""},
31
 
 
32
 
        {"get_block2",          (PyCFunction)Matrix4f_get_block2,       METH_VARARGS,
33
 
         ""},
34
 
        {"set_block2",          (PyCFunction)Matrix4f_set_block2,       METH_VARARGS,
35
 
         ""},
36
 
        {"get_block3",          (PyCFunction)Matrix4f_get_block3,       METH_VARARGS,
37
 
         ""},
38
 
        {"set_block3",          (PyCFunction)Matrix4f_set_block3,       METH_VARARGS,
39
 
         ""},
40
 
        {"get_col",                     (PyCFunction)Matrix4f_get_col,          METH_VARARGS,
41
 
         ""},
42
 
        {"set_col",                     (PyCFunction)Matrix4f_set_col,          METH_VARARGS,
43
 
         ""},
44
 
        {"get_row",                     (PyCFunction)Matrix4f_get_row,          METH_VARARGS,
45
 
         ""},
46
 
        {"set_row",                     (PyCFunction)Matrix4f_set_row,          METH_VARARGS,
47
 
         ""},
48
 
 
49
 
        {NULL}
50
 
};
51
 
 
52
 
PyNumberMethods Matrix4f_numbermethods = {
53
 
        Matrix4f_add,                           // nb_add
54
 
        Matrix4f_subtract,                      // nb_subtract
55
 
        Matrix4f_multiply,                      // nb_multiply
56
 
        Matrix4f_divide,                        // nb_divide
57
 
        0,                                                      // nb_remainder
58
 
        0,                                                      // nb_divmod
59
 
        0,                                                      // nb_power
60
 
        Matrix4f_negative,                      // nb_negative
61
 
        0,                                                      // nb_positive
62
 
        0,                                                      // nb_absolute
63
 
        0,                                                      // nb_nonzero
64
 
        0,                                                      // nb_invert
65
 
        0,                                                      // nb_lshift
66
 
        0,                                                      // nb_rshift
67
 
        0,                                                      // nb_and
68
 
        0,                                                      // nb_xor
69
 
        0,                                                      // nb_or
70
 
        0,                                                      // nb_coerce
71
 
        0,                                                      // nb_int
72
 
        0,                                                      // nb_long
73
 
        0,                                                      // nb_float
74
 
        0,                                                      // nb_oct
75
 
        0,                                                      // nb_hex
76
 
        Matrix4f_inplace_add,           // nb_inplace_add
77
 
        Matrix4f_inplace_subtract,      // nb_inplace_subtract
78
 
        Matrix4f_inplace_multiply,      // nb_inplace_multiply
79
 
        Matrix4f_inplace_divide,        // nb_inplace_divide
80
 
};
81
 
 
82
 
PyMappingMethods Matrix4f_mappingmethods = {
83
 
        (lenfunc)Matrix4f_length,                               // mp_length
84
 
        (binaryfunc)Matrix4f_subscript,                 // mp_subscript
85
 
        (objobjargproc)Matrix4f_ass_subscript,  // mp_ass_subscript
86
 
};
87
 
 
88
 
PyTypeObject Matrix4fType = {
89
 
        PyObject_HEAD_INIT(NULL)
90
 
 
91
 
        0,                                                              // ob_size
92
 
        "pyeigen.Matrix4f",                             // tp_name
93
 
        sizeof(Matrix4f),                               // tp_basicsize
94
 
        0,                                                              // tp_itemsize
95
 
        0,                                                              // tp_dealloc
96
 
        0,                                                              // tp_print
97
 
        0,                                                              // tp_getattr
98
 
        0,                                                              // tp_setattr
99
 
        0,                                                              // tp_compare
100
 
        (reprfunc)Matrix4f_repr,                // tp_repr
101
 
        &Matrix4f_numbermethods,                // tp_as_number
102
 
        0,                                                              // tp_as_sequence
103
 
        &Matrix4f_mappingmethods,               // tp_as_mapping
104
 
        0,                                                              // tp_hash
105
 
        0,                                                              // tp_call
106
 
        0,                                                              // tp_str
107
 
        0,                                                              // tp_getattro
108
 
        0,                                                              // tp_setattro
109
 
        0,                                                              // tp_as_buffer
110
 
        Py_TPFLAGS_DEFAULT |                    // tp_flags
111
 
        Py_TPFLAGS_BASETYPE |
112
 
        Py_TPFLAGS_CHECKTYPES,
113
 
        0,                                                              // tp_doc
114
 
        0,                                                              // tp_traverse
115
 
        0,                                                              // tp_clear
116
 
        0,                                                              // tp_richcompare
117
 
        0,                                                              // tp_weaklistoffset
118
 
        0,                                                              // tp_iter
119
 
        0,                                                              // tp_iternext
120
 
        Matrix4f_methods,                               // tp_methods
121
 
        0,                                                              // tp_members
122
 
        Matrix4f_getset,                                // tp_getset
123
 
        0,                                                              // tp_base
124
 
        0,                                                              // tp_dict
125
 
        0,                                                              // tp_descr_get
126
 
        0,                                                              // tp_descr_set
127
 
        0,                                                              // tp_dictoffset
128
 
        (initproc)Matrix4f_init,                // tp_init
129
 
        0,                                                              // tp_alloc
130
 
        Matrix4f_new,                                   // tp_new
131
 
        0,                                                              // tp_free
132
 
        0,                                                              // tp_is_gc
133
 
        0,                                                              // tp_bases
134
 
        0,                                                              // tp_mro
135
 
        0,                                                              // tp_cache
136
 
        0,                                                              // tp_subclasses
137
 
        0,                                                              // tp_weaklist
138
 
        0,                                                              // tp_del
139
 
        0,                                                              // tp_version_tag
140
 
};
141
 
 
142
 
// Helpers
143
 
int Matrix4f_Check(PyObject* p)
144
 
{
145
 
        return p->ob_type == &Matrix4fType;
146
 
}
147
 
 
148
 
int Matrix4f_ParseKey(PyObject* key, Py_ssize_t& key1, Py_ssize_t& key2)
149
 
{
150
 
        if(!PyArg_ParseTuple(key, "nn", &key1, &key2))
151
 
                return 0;
152
 
 
153
 
        if(key1 < 0)
154
 
                key1 += 4;
155
 
        if(key2 < 0)
156
 
                key2 += 4;
157
 
 
158
 
        if(key1 >= 4 || key2 >= 4)
159
 
        {
160
 
                PyErr_SetString(PyExc_IndexError, "index out of range");
161
 
                return 0;
162
 
        }
163
 
 
164
 
        return 1;
165
 
}
166
 
 
167
 
// Construction
168
 
PyObject* Matrix4f_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
169
 
{
170
 
        return type->tp_alloc(type, 0);
171
 
}
172
 
 
173
 
int Matrix4f_init(Matrix4f* self, PyObject* args, PyObject* kwds)
174
 
{
175
 
        if(!Matrix4f_set(self, args))
176
 
                return -1;
177
 
 
178
 
        return 0;
179
 
}
180
 
 
181
 
// Properties
182
 
 
183
 
// Methods
184
 
PyObject* Matrix4f_set(Matrix4f* self, PyObject* args)
185
 
{
186
 
        float m11 = 0.0f, m12 = 0.0f, m13 = 0.0f, m14 = 0.0f;
187
 
        float m21 = 0.0f, m22 = 0.0f, m23 = 0.0f, m24 = 0.0f;
188
 
        float m31 = 0.0f, m32 = 0.0f, m33 = 0.0f, m34 = 0.0f;
189
 
        float m41 = 0.0f, m42 = 0.0f, m43 = 0.0f, m44 = 0.0f;
190
 
        if(!PyArg_ParseTuple(args, "|ffffffffffffffff",
191
 
                &m11, &m12, &m13, &m14,
192
 
                &m21, &m22, &m23, &m24,
193
 
                &m31, &m32, &m33, &m34,
194
 
                &m41, &m42, &m43, &m44))
195
 
                return NULL;
196
 
 
197
 
        self->matrix << m11, m12, m13, m14,
198
 
                m21, m22, m23, m24,
199
 
                m31, m32, m33, m34,
200
 
                m41, m42, m43, m44;
201
 
        Py_RETURN_NONE;
202
 
}
203
 
 
204
 
PyObject* Matrix4f_set_zero(Matrix4f* self, PyObject* noargs)
205
 
{
206
 
        self->matrix.setZero();
207
 
        Py_RETURN_NONE;
208
 
}
209
 
 
210
 
PyObject* Matrix4f_set_ones(Matrix4f* self, PyObject* noargs)
211
 
{
212
 
        self->matrix.setOnes();
213
 
        Py_RETURN_NONE;
214
 
}
215
 
 
216
 
PyObject* Matrix4f_set_identity(Matrix4f* self, PyObject* noargs)
217
 
{
218
 
        self->matrix.setIdentity();
219
 
        Py_RETURN_NONE;
220
 
}
221
 
 
222
 
PyObject* Matrix4f_set_constant(Matrix4f* self, PyObject* args)
223
 
{
224
 
        float constant = 0.0f;
225
 
        if(!PyArg_ParseTuple(args, "f", &constant))
226
 
                return NULL;
227
 
 
228
 
        self->matrix.setConstant(constant);
229
 
        Py_RETURN_NONE;
230
 
}
231
 
 
232
 
PyObject* Matrix4f_set_random(Matrix4f* self, PyObject* noargs)
233
 
{
234
 
        self->matrix.setRandom();
235
 
        Py_RETURN_NONE;
236
 
}
237
 
 
238
 
PyObject* Matrix4f_get_block2(Matrix4f* self, PyObject* args)
239
 
{
240
 
        Py_ssize_t i = 0, j = 0;
241
 
        if(!PyArg_ParseTuple(args, "nn", &i, &j))
242
 
                return NULL;
243
 
 
244
 
        if(i < 0)
245
 
                i += 4;
246
 
        if(j < 0)
247
 
                j += 4;
248
 
 
249
 
        if(i < 0 || i > 2 || j < 0 || j > 2)
250
 
        {
251
 
                PyErr_SetString(PyExc_IndexError, "index out of range");
252
 
                return NULL;
253
 
        }
254
 
 
255
 
        Matrix2f* result = PyObject_New(Matrix2f, &Matrix2fType);
256
 
        if(result != NULL)
257
 
                result->matrix = self->matrix.block<2, 2>(i, j);
258
 
 
259
 
        return (PyObject*)result;
260
 
}
261
 
 
262
 
PyObject* Matrix4f_set_block2(Matrix4f* self, PyObject* args)
263
 
{
264
 
        Py_ssize_t i = 0, j = 0;
265
 
        Matrix2f* value = NULL;
266
 
        if(!PyArg_ParseTuple(args, "nnO!", &i, &j, &Matrix2fType, &value))
267
 
                return NULL;
268
 
 
269
 
        if(i < 0)
270
 
                i += 4;
271
 
        if(j < 0)
272
 
                j += 4;
273
 
 
274
 
        if(i < 0 || i > 2 || j < 0 || j > 2)
275
 
        {
276
 
                PyErr_SetString(PyExc_IndexError, "index out of range");
277
 
                return NULL;
278
 
        }
279
 
 
280
 
        self->matrix.block<2, 2>(i, j) = value->matrix;
281
 
        Py_RETURN_NONE;
282
 
}
283
 
 
284
 
PyObject* Matrix4f_get_block3(Matrix4f* self, PyObject* args)
285
 
{
286
 
        Py_ssize_t i = 0, j = 0;
287
 
        if(!PyArg_ParseTuple(args, "nn", &i, &j))
288
 
                return NULL;
289
 
 
290
 
        if(i < 0)
291
 
                i += 4;
292
 
        if(j < 0)
293
 
                j += 4;
294
 
 
295
 
        if(i < 0 || i > 1 || j < 0 || j > 1)
296
 
        {
297
 
                PyErr_SetString(PyExc_IndexError, "index out of range");
298
 
                return NULL;
299
 
        }
300
 
 
301
 
        Matrix3f* result = PyObject_New(Matrix3f, &Matrix3fType);
302
 
        if(result != NULL)
303
 
                result->matrix = self->matrix.block<3, 3>(i, j);
304
 
 
305
 
        return (PyObject*)result;
306
 
}
307
 
 
308
 
PyObject* Matrix4f_set_block3(Matrix4f* self, PyObject* args)
309
 
{
310
 
        Py_ssize_t i = 0, j = 0;
311
 
        Matrix3f* value = NULL;
312
 
        if(!PyArg_ParseTuple(args, "nnO!", &i, &j, &Matrix3fType, &value))
313
 
                return NULL;
314
 
 
315
 
        if(i < 0)
316
 
                i += 4;
317
 
        if(j < 0)
318
 
                j += 4;
319
 
 
320
 
        if(i < 0 || i > 1 || j < 0 || j > 1)
321
 
        {
322
 
                PyErr_SetString(PyExc_IndexError, "index out of range");
323
 
                return NULL;
324
 
        }
325
 
 
326
 
        self->matrix.block<3, 3>(i, j) = value->matrix;
327
 
        Py_RETURN_NONE;
328
 
}
329
 
 
330
 
PyObject* Matrix4f_get_col(Matrix4f* self, PyObject* args)
331
 
{
332
 
        Py_ssize_t index;
333
 
        if(!PyArg_ParseTuple(args, "n", &index))
334
 
                return NULL;
335
 
 
336
 
        if(index < 0 || index >= 2)
337
 
        {
338
 
                PyErr_SetString(PyExc_IndexError, "index out of range");
339
 
                return NULL;
340
 
        }
341
 
 
342
 
        Vector4f* result = PyObject_New(Vector4f, &Vector4fType);
343
 
        if(result != NULL)
344
 
                result->vector = self->matrix.col(index);
345
 
 
346
 
        return (PyObject*)result;
347
 
}
348
 
 
349
 
PyObject* Matrix4f_set_col(Matrix4f* self, PyObject* args)
350
 
{
351
 
        Py_ssize_t index;
352
 
        Vector4f* value = NULL;
353
 
        if(!PyArg_ParseTuple(args, "nO!", &index, &Vector4fType, &value))
354
 
                return NULL;
355
 
 
356
 
        if(index < 0 || index >= 2)
357
 
        {
358
 
                PyErr_SetString(PyExc_IndexError, "index out of range");
359
 
                return NULL;
360
 
        }
361
 
 
362
 
        self->matrix.col(index) = value->vector;
363
 
        Py_RETURN_NONE;
364
 
}
365
 
 
366
 
PyObject* Matrix4f_get_row(Matrix4f* self, PyObject* args)
367
 
{
368
 
        Py_ssize_t index;
369
 
        if(!PyArg_ParseTuple(args, "n", &index))
370
 
                return NULL;
371
 
 
372
 
        if(index < 0 || index >= 2)
373
 
        {
374
 
                PyErr_SetString(PyExc_IndexError, "index out of range");
375
 
                return NULL;
376
 
        }
377
 
 
378
 
        Vector4f* result = PyObject_New(Vector4f, &Vector4fType);
379
 
        if(result != NULL)
380
 
                result->vector = self->matrix.row(index);
381
 
 
382
 
        return (PyObject*)result;
383
 
}
384
 
 
385
 
PyObject* Matrix4f_set_row(Matrix4f* self, PyObject* args)
386
 
{
387
 
        Py_ssize_t index;
388
 
        Vector4f* value = NULL;
389
 
        if(!PyArg_ParseTuple(args, "nO!", &index, &Vector4fType, &value))
390
 
                return NULL;
391
 
 
392
 
        if(index < 0 || index >= 2)
393
 
        {
394
 
                PyErr_SetString(PyExc_IndexError, "index out of range");
395
 
                return NULL;
396
 
        }
397
 
 
398
 
        self->matrix.row(index) = value->vector;
399
 
        Py_RETURN_NONE;
400
 
}
401
 
 
402
 
// Number methods
403
 
PyObject* Matrix4f_add(PyObject* o1, PyObject* o2)
404
 
{
405
 
        if(!Matrix4f_Check(o1) || !Matrix4f_Check(o2))
406
 
                RETURN_NOTIMPLEMENTED;
407
 
 
408
 
        Matrix4f* m1 = (Matrix4f*)o1;
409
 
        Matrix4f* m2 = (Matrix4f*)o2;
410
 
        Matrix4f* result = PyObject_New(Matrix4f, &Matrix4fType);
411
 
        if(result != NULL)
412
 
                result->matrix = m1->matrix + m2->matrix;
413
 
 
414
 
        return (PyObject*)result;
415
 
}
416
 
 
417
 
PyObject* Matrix4f_subtract(PyObject* o1, PyObject* o2)
418
 
{
419
 
        if(!Matrix4f_Check(o1) || !Matrix4f_Check(o2))
420
 
                RETURN_NOTIMPLEMENTED;
421
 
 
422
 
        Matrix4f* m1 = (Matrix4f*)o1;
423
 
        Matrix4f* m2 = (Matrix4f*)o2;
424
 
        Matrix4f* result = PyObject_New(Matrix4f, &Matrix4fType);
425
 
        if(result != NULL)
426
 
                result->matrix = m1->matrix - m2->matrix;
427
 
 
428
 
        return (PyObject*)result;
429
 
}
430
 
 
431
 
PyObject* Matrix4f_multiply(PyObject* o1, PyObject* o2)
432
 
{
433
 
        Matrix4f* m;
434
 
        float scalar;
435
 
 
436
 
        // Matrix multiply
437
 
        if(Matrix4f_Check(o1) && Matrix4f_Check(o2))
438
 
        {
439
 
                Matrix4f* m1 = (Matrix4f*)o1;
440
 
                Matrix4f* m2 = (Matrix4f*)o2;
441
 
                Matrix4f* result = PyObject_New(Matrix4f, &Matrix4fType);
442
 
                if(result != NULL)
443
 
                        result->matrix = m1->matrix * m2->matrix;
444
 
 
445
 
                return (PyObject*)result;
446
 
        }
447
 
        // Scalar multiply
448
 
        else if(Matrix4f_Check(o1) && PyNumber_Check(o2))
449
 
        {
450
 
                m = (Matrix4f*)o1;
451
 
                scalar = (float)PyFloat_AsDouble(o2);
452
 
                if(PyErr_Occurred() != NULL)
453
 
                        return NULL;
454
 
 
455
 
        }
456
 
        else if(PyNumber_Check(o1) && Matrix4f_Check(o2))
457
 
        {
458
 
                scalar = (float)PyFloat_AsDouble(o1);
459
 
                m = (Matrix4f*)o2;
460
 
                if(PyErr_Occurred() != NULL)
461
 
                        return NULL;
462
 
        }
463
 
        else
464
 
                RETURN_NOTIMPLEMENTED;
465
 
 
466
 
        Matrix4f* result = PyObject_New(Matrix4f, &Matrix4fType);
467
 
        if(result != NULL)
468
 
                result->matrix = m->matrix * scalar;
469
 
 
470
 
        return (PyObject*)result;
471
 
}
472
 
 
473
 
PyObject* Matrix4f_divide(PyObject* o1, PyObject* o2)
474
 
{
475
 
        if(!Matrix4f_Check(o1) || !PyNumber_Check(o2))
476
 
                RETURN_NOTIMPLEMENTED;
477
 
 
478
 
        Matrix4f* m = (Matrix4f*)o1;
479
 
        float scalar = (float)PyFloat_AsDouble(o2);
480
 
        if(PyErr_Occurred() != NULL)
481
 
                return NULL;
482
 
 
483
 
        Matrix4f* result = PyObject_New(Matrix4f, &Matrix4fType);
484
 
        if(result != NULL)
485
 
                result->matrix = m->matrix / scalar;
486
 
 
487
 
        return (PyObject*)result;
488
 
}
489
 
 
490
 
PyObject* Matrix4f_negative(PyObject* o)
491
 
{
492
 
        if(!Matrix4f_Check(o))
493
 
                RETURN_NOTIMPLEMENTED;
494
 
 
495
 
        Matrix4f* m = (Matrix4f*)o;
496
 
        Matrix4f* result = PyObject_New(Matrix4f, &Matrix4fType);
497
 
        if(result != NULL)
498
 
                result->matrix = -m->matrix;
499
 
 
500
 
        return (PyObject*)result;
501
 
}
502
 
 
503
 
PyObject* Matrix4f_inplace_add(PyObject* o1, PyObject* o2)
504
 
{
505
 
        if(!Matrix4f_Check(o1) || !PyNumber_Check(o2))
506
 
                RETURN_NOTIMPLEMENTED;
507
 
 
508
 
        Matrix4f* m1 = (Matrix4f*)o1;
509
 
        Matrix4f* m2 = (Matrix4f*)o2;
510
 
        m1->matrix += m2->matrix;
511
 
 
512
 
        return o1;
513
 
}
514
 
 
515
 
PyObject* Matrix4f_inplace_subtract(PyObject* o1, PyObject* o2)
516
 
{
517
 
        if(!Matrix4f_Check(o1) || !PyNumber_Check(o2))
518
 
                RETURN_NOTIMPLEMENTED;
519
 
 
520
 
        Matrix4f* m1 = (Matrix4f*)o1;
521
 
        Matrix4f* m2 = (Matrix4f*)o2;
522
 
        m1->matrix -= m2->matrix;
523
 
 
524
 
        return o1;
525
 
}
526
 
 
527
 
PyObject* Matrix4f_inplace_multiply(PyObject* o1, PyObject* o2)
528
 
{
529
 
        if(!Matrix4f_Check(o1))
530
 
                RETURN_NOTIMPLEMENTED;
531
 
 
532
 
        Matrix4f* m1 = (Matrix4f*)o1;
533
 
        Matrix4f* m2;
534
 
        float scalar;
535
 
 
536
 
        // Matrix multiply
537
 
        if(Matrix4f_Check(o2))
538
 
        {
539
 
                m2 = (Matrix4f*)o2;
540
 
                m1->matrix *= m2->matrix;
541
 
        }
542
 
        // Scalar multiply
543
 
        else if(PyNumber_Check(o2))
544
 
        {
545
 
                scalar = (float)PyFloat_AsDouble(o2);
546
 
                if(PyErr_Occurred() != NULL)
547
 
                        return NULL;
548
 
 
549
 
                m1->matrix *= scalar;
550
 
        }
551
 
        else
552
 
                RETURN_NOTIMPLEMENTED;
553
 
 
554
 
        return (PyObject*)m1;
555
 
}
556
 
 
557
 
PyObject* Matrix4f_inplace_divide(PyObject* o1, PyObject* o2)
558
 
{
559
 
        if(!Matrix4f_Check(o1) || !PyNumber_Check(o2))
560
 
                RETURN_NOTIMPLEMENTED;
561
 
 
562
 
        Matrix4f* m = (Matrix4f*)o1;
563
 
        float scalar = (float)PyFloat_AsDouble(o2);
564
 
        if(PyErr_Occurred() != NULL)
565
 
                return NULL;
566
 
 
567
 
        m->matrix /= scalar;
568
 
 
569
 
        return (PyObject*)m;
570
 
}
571
 
 
572
 
// Mapping methods
573
 
Py_ssize_t Matrix4f_length(Matrix4f* self)
574
 
{
575
 
        return 16;
576
 
}
577
 
 
578
 
PyObject* Matrix4f_subscript(Matrix4f* self, PyObject* key)
579
 
{
580
 
        Py_ssize_t key1, key2;
581
 
        if(!Matrix4f_ParseKey(key, key1, key2))
582
 
                return NULL;
583
 
 
584
 
        return PyFloat_FromDouble(self->matrix(key1, key2));
585
 
}
586
 
 
587
 
int Matrix4f_ass_subscript(Matrix4f* self, PyObject* key, PyObject* value)
588
 
{
589
 
        Py_ssize_t key1, key2;
590
 
        if(!Matrix4f_ParseKey(key, key1, key2))
591
 
                return -1;
592
 
 
593
 
        self->matrix(key1, key2) = (float)PyFloat_AsDouble(value);
594
 
        return 0;
595
 
}
596
 
 
597
 
// Special methods
598
 
PyObject* Matrix4f_repr(Matrix4f* self)
599
 
{
600
 
        char buffer[1024];
601
 
        _snprintf(buffer, 1024, "Matrix4f(%f, %f, %f, %f,\n         %f, %f, %f, %f,\n         %f, %f, %f, %f\n         %f, %f, %f, %f)",
602
 
                self->matrix(0, 0), self->matrix(0, 1), self->matrix(0, 2), self->matrix(0, 3),
603
 
                self->matrix(1, 0), self->matrix(1, 1), self->matrix(1, 2), self->matrix(1, 3),
604
 
                self->matrix(2, 0), self->matrix(2, 1), self->matrix(2, 2), self->matrix(2, 3),
605
 
                self->matrix(3, 0), self->matrix(3, 1), self->matrix(3, 2), self->matrix(3, 3));
606
 
        return PyString_FromString(buffer);
607
 
}