1 /*
2  * Copyright (c) 2007 Ivan Leben
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library in the file COPYING;
16  * if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  *
19  */
20 
21 #include "shVectors.h"
22 
23 #define _ITEM_T SHVector2
24 #define _ARRAY_T SHVector2Array
25 #define _FUNC_T shVector2Array
26 #define _COMPARE_T(v1,v2) EQ2V(v1,v2)
27 #define _ARRAY_DEFINE
28 #include "shArrayBase.h"
29 
SHVector2_ctor(SHVector2 * v)30 void SHVector2_ctor(SHVector2 *v) {
31   v->x=0.0f; v->y=0.0f;
32 }
33 
SHVector2_dtor(SHVector2 * v)34 void SHVector2_dtor(SHVector2 *v) {
35 }
36 
SHVector3_ctor(SHVector3 * v)37 void SHVector3_ctor(SHVector3 *v) {
38 #ifdef SHIVA_USE_SIMD
39   v->vec = _mm_setzero_ps();
40 #else
41   v->x=0.0f; v->y=0.0f; v->z=0.0f;
42 #endif
43 }
44 
SHVector3_dtor(SHVector3 * v)45 void SHVector3_dtor(SHVector3 *v) {
46 }
47 
SHVector4_ctor(SHVector4 * v)48 void SHVector4_ctor(SHVector4 *v) {
49 #ifdef SHIVA_USE_SIMD
50   v->vec = _mm_setzero_ps();
51 #else
52   v->x=0.0f; v->y=0.0f; v->z=0.0f; v->w=0.0f;
53 #endif
54 }
55 
SHVector4_dtor(SHVector4 * v)56 void SHVector4_dtor(SHVector4 *v) {
57 }
58 
SHRectangle_ctor(SHRectangle * r)59 void SHRectangle_ctor(SHRectangle *r) {
60 #ifdef SHIVA_USE_SIMD
61   r->vec = _mm_setzero_ps();
62 #else
63   r->x=0.0f; r->y=0.0f; r->w=0.0f; r->h=0.0f;
64 #endif
65 }
66 
SHRectangle_dtor(SHRectangle * r)67 void SHRectangle_dtor(SHRectangle *r) {
68 }
69 
shRectangleSet(SHRectangle * r,SHfloat x,SHfloat y,SHfloat w,SHfloat h)70 void shRectangleSet(SHRectangle *r, SHfloat x,
71                     SHfloat y, SHfloat w, SHfloat h)
72 {
73   r->x=x; r->y=y; r->w=w; r->h=h;
74 }
75 
SHMatrix3x3_ctor(SHMatrix3x3 * mt)76 void SHMatrix3x3_ctor(SHMatrix3x3 *mt)
77 {
78   IDMAT((*mt));
79 }
80 
SHMatrix3x3_dtor(SHMatrix3x3 * mt)81 void SHMatrix3x3_dtor(SHMatrix3x3 *mt)
82 {
83 }
84 
shMatrixToGL(SHMatrix3x3 * m,SHfloat mgl[16])85 void shMatrixToGL(SHMatrix3x3 *m, SHfloat mgl[16])
86 {
87   /* When 2D vectors are specified OpenGL defaults Z to 0.0f so we
88      have to shift the third column of our 3x3 matrix to right */
89   mgl[0] = m->m[0][0]; mgl[4] = m->m[0][1]; mgl[8]  = 0.0f; mgl[12] = m->m[0][2];
90   mgl[1] = m->m[1][0]; mgl[5] = m->m[1][1]; mgl[9]  = 0.0f; mgl[13] = m->m[1][2];
91   mgl[2] = m->m[2][0]; mgl[6] = m->m[2][1]; mgl[10] = 1.0f; mgl[14] = m->m[2][1];
92   mgl[3] = 0.0f;       mgl[7] = 0.0f;       mgl[11] = 0.0f; mgl[15] = 1.0f;
93 }
94 
shInvertMatrix(SHMatrix3x3 * m,SHMatrix3x3 * mout)95 int shInvertMatrix(SHMatrix3x3 *m, SHMatrix3x3 *mout)
96 {
97   /* Calculate determinant */
98   SHfloat D0 = m->m[1][1]*m->m[2][2] - m->m[2][1]*m->m[1][2];
99   SHfloat D1 = m->m[2][0]*m->m[1][2] - m->m[1][0]*m->m[2][2];
100   SHfloat D2 = m->m[1][0]*m->m[2][1] - m->m[2][0]*m->m[1][1];
101   SHfloat D = m->m[0][0]*D0 + m->m[0][1]*D1 + m->m[0][2]*D2;
102 
103   /* Check if singular */
104   if( D == 0.0f ) return 0;
105   D = 1.0f / D;
106 
107   /* Calculate inverse */
108   mout->m[0][0] = D * D0;
109   mout->m[1][0] = D * D1;
110   mout->m[2][0] = D * D2;
111   mout->m[0][1] = D * (m->m[2][1]*m->m[0][2] - m->m[0][1]*m->m[2][2]);
112   mout->m[1][1] = D * (m->m[0][0]*m->m[2][2] - m->m[2][0]*m->m[0][2]);
113   mout->m[2][1] = D * (m->m[2][0]*m->m[0][1] - m->m[0][0]*m->m[2][1]);
114   mout->m[0][2] = D * (m->m[0][1]*m->m[1][2] - m->m[1][1]*m->m[0][2]);
115   mout->m[1][2] = D * (m->m[1][0]*m->m[0][2] - m->m[0][0]*m->m[1][2]);
116   mout->m[2][2] = D * (m->m[0][0]*m->m[1][1] - m->m[1][0]*m->m[0][1]);
117 
118   return 1;
119 }
120 
shVectorOrientation(SHVector2 * v)121 SHfloat shVectorOrientation(SHVector2 *v) {
122   SHfloat norm = (SHfloat)NORM2((*v));
123   SHfloat cosa = v->x/norm;
124   SHfloat sina = v->y/norm;
125   return (SHfloat)(sina>=0 ? SH_ACOS(cosa) : 2*PI-SH_ACOS(cosa));
126 }
127 
shLineLineXsection(SHVector2 * o1,SHVector2 * v1,SHVector2 * o2,SHVector2 * v2,SHVector2 * xsection)128 int shLineLineXsection(SHVector2 *o1, SHVector2 *v1,
129                        SHVector2 *o2, SHVector2 *v2,
130                        SHVector2 *xsection)
131 {
132   SHfloat rightU = o2->x - o1->x;
133   SHfloat rightD = o2->y - o1->y;
134 
135   SHfloat D  = v1->x  * (-v2->y) - v1->y   * (-v2->x);
136   SHfloat DX = rightU * (-v2->y) - rightD * (-v2->x);
137 /*SHfloat DY = v1.x   * rightD  - v1.y   * rightU;*/
138 
139   SHfloat t1;
140 
141   if (D == 0.0f)
142     return 0;
143 
144   t1 = DX / D;
145 
146   xsection->x = o1->x + t1*v1->x;
147   xsection->y = o1->y + t1*v1->y;
148   return 1;
149 }
150 
151 #ifdef SHIVA_USE_SIMD
152 # ifdef __SSE3__
153 # include <pmmintrin.h>
hsum_ps_sse(__m128 v)154 inline float hsum_ps_sse(__m128 v) {
155   __m128 shuf = _mm_movehdup_ps(v);
156   __m128 sums = _mm_add_ps(v, shuf);
157   shuf        = _mm_movehl_ps(shuf, sums);
158   sums        = _mm_add_ss(sums, shuf);
159   return        _mm_cvtss_f32(sums);
160 }
161 # else
hsum_ps_sse(__m128 v)162 inline float hsum_ps_sse(__m128 v) {
163   __m128 shuf   = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 3, 0, 1));
164   __m128 sums   = _mm_add_ps(v, shuf);
165   shuf          = _mm_movehl_ps(shuf, sums);
166   sums          = _mm_add_ss(sums, shuf);
167   return          _mm_cvtss_f32(sums);
168 }
169 # endif
170 #endif
171