/* * Copyright (c) 2006-2008 Hypertriton, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Basic matrix operations. */ #include #include "m.h" #include "m_bitstring.h" #include const M_MatrixOps *mMatOps = NULL; const M_MatrixOps44 *mMatOps44 = NULL; void M_MatrixInitEngine(void) { mMatOps = &mMatOps_FPU; mMatOps44 = &mMatOps44_FPU; if (HasSSE()) { #ifdef HAVE_SSE mMatOps44 = &mMatOps44_SSE; #elif defined(AG_DEBUG) AG_Verbose("SSE available, but disabled at compile time\n"); #endif } #ifdef AG_DEBUG AG_Verbose("Matrix operations: "); #if defined(INLINE_ALTIVEC) AG_Verbose("altivec (inline)\n"); #elif defined(INLINE_SSE3) AG_Verbose("sse3 (inline)\n"); #elif defined(INLINE_SSE2) AG_Verbose("sse2 (inline)\n"); #elif defined(INLINE_SSE) AG_Verbose("sse (inline)\n"); #else AG_Verbose("%s\n", mMatOps44->name); #endif #endif /* AG_DEBUG */ } void M_MatrixPrint44(const M_Matrix44 *A) { int m, n; for (n = 0; n < 4; n++) { for (m = 0; m < 4; m++) { printf("%f ", A->m[m][n]); } printf("\n"); } } M_Matrix44 M_ReadMatrix44(AG_DataSource *buf) { M_Matrix44 A; M_ReadMatrix44v(buf, &A); return (A); } void M_ReadMatrix44v(AG_DataSource *buf, M_Matrix44 *A) { M_Real *pm = &A->m[0][0]; int i; #if 0 /* * Trivial compression for sparse matrices. */ bitstr_t bit_decl(map0, 16); bitstr_t bit_decl(map1, 16); AG_Read(buf, &map0, sizeof(map0), 1); AG_Read(buf, &map1, sizeof(map1), 1); for (i = 0; i < 16; i++) { if (bit_test(map0, i)) { *pm = 0.0; } else if (bit_test(map1, i)) { *pm = 1.0; } else { *pm = (M_Real)AG_ReadDouble(buf); } pm++; } #else for (i = 0; i < 16; i++) { *pm = M_ReadReal(buf); pm++; } #endif } void M_WriteMatrix44(AG_DataSource *buf, const M_Matrix44 *A) { const M_Real *pm = &A->m[0][0]; int i; #if 0 /* * Trivial compression for sparse matrices. */ bitstr_t bit_decl(map0, 16); bitstr_t bit_decl(map1, 16); off_t offs; offs = AG_Tell(buf); AG_Seek(buf, 4, AG_SEEK_CUR); for (i = 0; i < 16; i++) { if (*pm == 0.0) { bit_set(map0, i); bit_clear(map1, i); } else if (*pm == 1.0) { bit_clear(map0, i); bit_set(map1, i); } else { bit_clear(map0, i); bit_clear(map1, i); AG_WriteDouble(buf, (M_Real)(*pm)); } pm++; } AG_WriteAt(buf, &map0, sizeof(map0), 1, offs); AG_WriteAt(buf, &map1, sizeof(map1), 1, offs+2); #else for (i = 0; i < 16; i++) { M_WriteReal(buf, *pm); pm++; } #endif }