Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Aug 29th, 2013  |  syntax: C++  |  size: 14.36 KB  |  views: 99  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /**
  2.   *
  3.   * Float4 header file, contains vector math
  4.   *
  5.   * Created By Vilem Otte, 2011
  6.   *
  7.   * If you use this library for any project, please let me know at vilem.otte@post.cz, I might add
  8.   * a link at your project at my site. As for the licence:
  9.   *
  10.   * Licence: WTFPL
  11.   *
  12.   *            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
  13.   *                    Version 2, December 2004
  14.   *
  15.   * Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
  16.   *
  17.   * Everyone is permitted to copy and distribute verbatim or modified
  18.   * copies of this license document, and changing it is allowed as long
  19.   * as the name is changed.
  20.   *
  21.   *            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
  22.   *   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
  23.   *
  24.   *  0. You just DO WHAT THE FUCK YOU WANT TO.
  25.   *
  26.   **/
  27.  
  28. #ifndef __FLOAT4__H__
  29. #define __FLOAT4__H__
  30.  
  31. #include "../../core/platform/platform.h"
  32.  
  33. #include <math.h>
  34.  
  35. #ifdef PLATFORM_SSE
  36.         #include <xmmintrin.h>
  37. #endif
  38.  
  39. #ifdef PLATFORM_SSE2
  40.         #include <emmintrin.h>
  41. #endif
  42.  
  43. #ifdef PLATFORM_SSE3
  44.         #include <pmmintrin.h>
  45. #endif
  46.  
  47. #ifdef PLATFORM_SSE4
  48.         #include <smmintrin.h>
  49. #endif
  50.  
  51. #include "../../core/memory/memory.h"
  52.  
  53. #define min(a, b) (a < b ? a : b)
  54. #define max(a, b) (a > b ? a : b)
  55.  
  56. struct ALIGN(16) float4
  57. {
  58. #ifdef PLATFORM_SSE
  59.         union
  60.         {
  61.                 struct
  62.                 {
  63.                         float x, y, z, w;
  64.                 };
  65.                 __m128 xmm;
  66.         };
  67. #else
  68.         float x, y, z, w;
  69. #endif
  70.  
  71.        
  72.         ///////////////////////////////////////////////////////////////////////////////////////////////////
  73.         /** Constructors                                                                                **/
  74.  
  75.         /* Default constructor */      
  76.         inline float4()
  77.         {      
  78. #ifdef PLATFORM_SSE            
  79.                 xmm = _mm_setzero_ps();
  80. #else
  81.                 x = y = z = w = 0.0f;
  82. #endif
  83.         }                      
  84.        
  85.         /* Float constructor */
  86.         explicit inline float4(float f)
  87.         {              
  88. #ifdef PLATFORM_SSE            
  89.                 xmm = _mm_set1_ps(f);
  90. #else
  91.                 x = y = z = w = f;
  92. #endif         
  93.         }                      
  94.        
  95.         /* Scalar constructor */       
  96.         inline float4(float _x, float _y, float _z, float _w)
  97.         {              
  98. #ifdef PLATFORM_SSE            
  99.                 xmm = _mm_setr_ps(_x, _y, _z, _w);
  100. #else
  101.                 x = _x;
  102.                 y = _y;
  103.                 z = _z;
  104.                 w = _w;
  105. #endif         
  106.         }              
  107.        
  108.         /* Array constructor (unaligned!!!) */
  109.         inline float4(const float* fv)
  110.         {      
  111. #ifdef PLATFORM_SSE    
  112.                 xmm = _mm_loadu_ps(fv);
  113. #else
  114.                 x = fv[0];
  115.                 y = fv[1];
  116.                 z = fv[2];
  117.                 w = fv[3];
  118. #endif         
  119.         }                      
  120.        
  121.         /* Copy constructor */
  122.         inline float4(const float4 &v)
  123.         {                      
  124. #ifdef PLATFORM_SSE    
  125.                 xmm = v.xmm;   
  126. #else
  127.                 x = v.x;
  128.                 y = v.y;
  129.                 z = v.z;
  130.                 w = v.w;
  131. #endif                 
  132.         }                      
  133.        
  134. #ifdef PLATFORM_SSE    
  135.         /* SSE constructor */
  136.         inline float4(const __m128 &_m)
  137.         {                      
  138.                 xmm = _m;              
  139.         }
  140. #endif
  141.  
  142.         ///////////////////////////////////////////////////////////////////////////////////////////////////
  143.         /** Accessing                                                                                   **/
  144.        
  145.         /* Direct access write */
  146.         inline float& operator[](int index)
  147.         {
  148.                 return reinterpret_cast<float *>(this)[index];
  149.         }
  150.  
  151.         /* Direct access read */
  152.         inline const float& operator[](int index) const
  153.         {
  154.                 return reinterpret_cast<const float *>(this)[index];
  155.         }
  156.  
  157.         /* Cast */
  158.         inline operator float* ()
  159.         {
  160.                 return reinterpret_cast<float *>(this);
  161.         }
  162.  
  163.         /* Const cast */
  164.         inline operator const float* () const
  165.         {
  166.                 return reinterpret_cast<const float *>(this);
  167.         }
  168.  
  169.         ///////////////////////////////////////////////////////////////////////////////////////////////////
  170.         /** Unary arithmetics                                                                           **/
  171.        
  172.         /* Scalar addition */
  173.         friend inline float4& operator += (float4& v, float f)
  174.         {
  175. #ifdef PLATFORM_SSE    
  176.                 v.xmm = _mm_add_ps(v.xmm, _mm_set1_ps(f));
  177. #else
  178.                 v.x += f;
  179.                 v.y += f;
  180.                 v.z += f;
  181.                 v.w += f;
  182. #endif
  183.                 return v;
  184.         }
  185.  
  186.         /* Vector addition */
  187.         friend inline float4& operator += (float4& v0, const float4& v1)
  188.         {
  189. #ifdef PLATFORM_SSE    
  190.                 v0.xmm = _mm_add_ps(v0.xmm, v1.xmm);
  191. #else
  192.                 v0.x += v1.x;
  193.                 v0.y += v1.y;
  194.                 v0.z += v1.z;
  195.                 v0.w += v1.w;
  196. #endif
  197.                 return v0;
  198.         }
  199.        
  200.         /* Scalar subtraction */
  201.         friend inline float4& operator -= (float4& v, float f)
  202.         {
  203. #ifdef PLATFORM_SSE    
  204.                 v.xmm = _mm_sub_ps(v.xmm, _mm_set1_ps(f));
  205. #else
  206.                 v.x -= f;
  207.                 v.y -= f;
  208.                 v.z -= f;
  209.                 v.w -= f;
  210. #endif
  211.                 return v;
  212.         }
  213.  
  214.         /* Sign negation */
  215.         friend inline const float4 operator - (const float4& v)
  216.         {
  217. #ifdef PLATFORM_SSE    
  218.                 return _mm_xor_ps(v.xmm, _mm_set1_ps(-0.f));
  219. #else
  220.                 float4 ret;
  221.                 ret.x = -v.x;
  222.                 ret.y = -v.y;
  223.                 ret.z = -v.z;
  224.                 ret.w = -v.w;
  225.                 return ret;
  226. #endif
  227.         }
  228.        
  229.         /* Vector subtraction */
  230.         friend inline float4& operator -= (float4& v0, const float4& v1)
  231.         {
  232. #ifdef PLATFORM_SSE    
  233.                 v0.xmm = _mm_sub_ps(v0.xmm, v1.xmm);
  234. #else
  235.                 v0.x -= v1.x;
  236.                 v0.y -= v1.y;
  237.                 v0.z -= v1.z;
  238.                 v0.w -= v1.w;
  239. #endif
  240.                 return v0;
  241.         }
  242.        
  243.         /* Scalar multiplication */
  244.         friend inline float4& operator *= (float4& v, float f)
  245.         {
  246. #ifdef PLATFORM_SSE    
  247.                 v.xmm = _mm_mul_ps(v.xmm, _mm_set1_ps(f));
  248. #else
  249.                 v.x *= f;
  250.                 v.y *= f;
  251.                 v.z *= f;
  252.                 v.w *= f;
  253. #endif
  254.                 return v;
  255.         }
  256.  
  257.         /* Vector multiplication */
  258.         friend inline float4& operator *= (float4& v0, const float4& v1)
  259.         {
  260. #ifdef PLATFORM_SSE    
  261.                 v0.xmm = _mm_mul_ps(v0.xmm, v1.xmm);
  262. #else
  263.                 v0.x *= v1.x;
  264.                 v0.y *= v1.y;
  265.                 v0.z *= v1.z;
  266.                 v0.w *= v1.w;
  267. #endif
  268.                 return v0;
  269.         }
  270.        
  271.         /* Scalar division */
  272.         friend inline float4& operator /= (float4& v, float f)
  273.         {
  274. #ifdef PLATFORM_SSE    
  275.                 v.xmm = _mm_div_ps(v.xmm, _mm_set1_ps(f));
  276. #else
  277.                 float rf = 1.0f / f;
  278.                 v.x *= rf;
  279.                 v.y *= rf;
  280.                 v.z *= rf;
  281.                 v.w *= rf;
  282. #endif
  283.                 return v;
  284.         }
  285.  
  286.         /* Vector division */
  287.         friend inline float4& operator /= (float4& v0, const float4& v1)
  288.         {
  289. #ifdef PLATFORM_SSE    
  290.                 v0.xmm = _mm_div_ps(v0.xmm, v1.xmm);
  291. #else
  292.                 v0.x /= v1.x;
  293.                 v0.y /= v1.y;
  294.                 v0.z /= v1.z;
  295.                 v0.w /= v1.w;
  296. #endif
  297.                 return v0;
  298.         }
  299.        
  300.         ///////////////////////////////////////////////////////////////////////////////////////////////////
  301.         /** Binary arithmetics                                                                          **/
  302.        
  303.         /* Addition */
  304.         friend inline const float4 operator + (float f, const float4& v)
  305.         {
  306. #ifdef PLATFORM_SSE    
  307.                 return _mm_add_ps(_mm_set1_ps(f), v.xmm);
  308. #else
  309.                 float4 ret;
  310.                 ret.x = f + v.x;
  311.                 ret.y = f + v.y;
  312.                 ret.z = f + v.z;
  313.                 ret.w = f + v.w;
  314.                 return ret;
  315. #endif
  316.         }
  317.  
  318.         friend inline const float4 operator + (const float4& v, float f)
  319.         {
  320. #ifdef PLATFORM_SSE    
  321.                 return _mm_add_ps(v.xmm, _mm_set1_ps(f));
  322. #else
  323.                 float4 ret;
  324.                 ret.x = v.x + f;
  325.                 ret.y = v.y + f;
  326.                 ret.z = v.z + f;
  327.                 ret.w = v.w + f;
  328.                 return ret;
  329. #endif
  330.         }
  331.  
  332.         friend inline const float4 operator + (const float4& v0, const float4& v1)
  333.         {
  334. #ifdef PLATFORM_SSE    
  335.                 return _mm_add_ps(v0.xmm, v1.xmm);
  336. #else
  337.                 float4 ret;
  338.                 ret.x = v0.x + v1.x;
  339.                 ret.y = v0.y + v1.y;
  340.                 ret.z = v0.z + v1.z;
  341.                 ret.w = v0.w + v1.w;
  342.                 return ret;
  343. #endif
  344.         }
  345.        
  346.         /* Subtraction */
  347.         friend inline const float4 operator - (float f, const float4& v)
  348.         {
  349. #ifdef PLATFORM_SSE    
  350.                 return _mm_sub_ps(_mm_set1_ps(f), v.xmm);
  351. #else
  352.                 float4 ret;
  353.                 ret.x = f - v.x;
  354.                 ret.y = f - v.y;
  355.                 ret.z = f - v.z;
  356.                 ret.w = f - v.w;
  357.                 return ret;
  358. #endif
  359.         }
  360.  
  361.         friend inline const float4 operator - (const float4& v, float f)
  362.         {
  363. #ifdef PLATFORM_SSE    
  364.                 return _mm_sub_ps(v.xmm, _mm_set1_ps(f));
  365. #else
  366.                 float4 ret;
  367.                 ret.x = v.x - f;
  368.                 ret.y = v.y - f;
  369.                 ret.z = v.z - f;
  370.                 ret.w = v.w - f;
  371.                 return ret;
  372. #endif
  373.         }
  374.  
  375.         friend inline const float4 operator - (const float4& v0, const float4& v1)
  376.         {
  377. #ifdef PLATFORM_SSE    
  378.                 return _mm_sub_ps(v0.xmm, v1.xmm);
  379. #else
  380.                 float4 ret;
  381.                 ret.x = v0.x - v1.x;
  382.                 ret.y = v0.y - v1.y;
  383.                 ret.z = v0.z - v1.z;
  384.                 ret.w = v0.w - v1.w;
  385.                 return ret;
  386. #endif
  387.         }
  388.        
  389.         /* Multiplication */
  390.         friend inline const float4 operator * (float f, const float4& v)
  391.         {
  392. #ifdef PLATFORM_SSE    
  393.                 return _mm_mul_ps(_mm_set1_ps(f), v.xmm);
  394. #else
  395.                 float4 ret;
  396.                 ret.x = f * v.x;
  397.                 ret.y = f * v.y;
  398.                 ret.z = f * v.z;
  399.                 ret.w = f * v.w;
  400.                 return ret;
  401. #endif
  402.         }
  403.  
  404.         friend inline const float4 operator * (const float4& v, float f)
  405.         {
  406. #ifdef PLATFORM_SSE    
  407.                 return _mm_mul_ps(v.xmm, _mm_set1_ps(f));
  408. #else
  409.                 float4 ret;
  410.                 ret.x = v.x * f;
  411.                 ret.y = v.y * f;
  412.                 ret.z = v.z * f;
  413.                 ret.w = v.w * f;
  414.                 return ret;
  415. #endif
  416.         }
  417.  
  418.         friend inline const float4 operator * (const float4& v0, const float4& v1)
  419.         {
  420. #ifdef PLATFORM_SSE    
  421.                 return _mm_mul_ps(v0.xmm, v1.xmm);
  422. #else
  423.                 float4 ret;
  424.                 ret.x = v0.x * v1.x;
  425.                 ret.y = v0.y * v1.y;
  426.                 ret.z = v0.z * v1.z;
  427.                 ret.w = v0.w * v1.w;
  428.                 return ret;
  429. #endif
  430.         }
  431.        
  432.         /* Division */
  433.         friend inline const float4 operator / (float f, const float4& v)
  434.         {
  435. #ifdef PLATFORM_SSE    
  436.                 return _mm_div_ps(_mm_set1_ps(f), v.xmm);
  437. #else
  438.                 float4 ret;
  439.                 ret.x = f / v.x;
  440.                 ret.y = f / v.y;
  441.                 ret.z = f / v.z;
  442.                 ret.w = f / v.w;
  443.                 return ret;
  444. #endif
  445.         }
  446.  
  447.         friend inline const float4 operator / (const float4& v, float f)
  448.         {
  449. #ifdef PLATFORM_SSE    
  450.                 return _mm_div_ps(v.xmm, _mm_set1_ps(f));
  451. #else
  452.                 float rf = 1.0f / f;
  453.                 float4 ret;
  454.                 ret.x = v.x * rf;
  455.                 ret.y = v.y * rf;
  456.                 ret.z = v.z * rf;
  457.                 ret.w = v.w * rf;
  458.                 return ret;
  459. #endif
  460.         }
  461.  
  462.         friend inline const float4 operator / (const float4& v0, const float4& v1)
  463.         {
  464. #ifdef PLATFORM_SSE    
  465.                 return _mm_div_ps(v0.xmm, v1.xmm);
  466. #else
  467.                 float4 ret;
  468.                 ret.x = v0.x / v1.x;
  469.                 ret.y = v0.y / v1.y;
  470.                 ret.z = v0.z / v1.z;
  471.                 ret.w = v0.w / v1.w;
  472.                 return ret;
  473. #endif
  474.         }
  475.        
  476.         ///////////////////////////////////////////////////////////////////////////////////////////////////
  477.         /** Additional arithmetics                                                                      **/
  478.        
  479.         /* Horizontal add */
  480.         inline friend float4 hadd(const float4& a)
  481.         {
  482. #ifdef PLATFORM_SSE3
  483.                 __m128 b = _mm_hadd_ps(a.xmm, a.xmm);
  484.                 return _mm_hadd_ps(b, b);
  485. #elif defined PLATFORM_SSE
  486.                 return float4(_mm_add_ss(a.xmm, _mm_add_ss(_mm_shuffle_ps(a.xmm, a.xmm, 1), _mm_add_ss(_mm_shuffle_ps(a.xmm, a.xmm, 2), _mm_shuffle_ps(a.xmm, a.xmm, 3)))));
  487. #else
  488.                 float4 ret;
  489.                 ret.x = a.x + a.y + a.z + a.w;
  490.                 ret.w = ret.z = ret.y = ret.x;
  491.                 return ret;
  492. #endif
  493.         }
  494.        
  495.         /* Absolute value */
  496.         friend inline const float4 abs(const float4& v)
  497.         {
  498. #ifdef PLATFORM_SSE
  499.                 return _mm_andnot_ps(_mm_set1_ps(-0.f), v.xmm);
  500. #else
  501.                 float4 ret;
  502.                 ret.x = fabsf(v.x);
  503.                 ret.y = fabsf(v.y);
  504.                 ret.z = fabsf(v.z);
  505.                 ret.w = fabsf(v.w);
  506.                 return ret;
  507. #endif
  508.         }
  509.        
  510.         /* Clamp between values */
  511.         friend inline const float4 clamp(const float4& v0, float f1, float f2)
  512.         {
  513. #ifdef PLATFORM_SSE
  514.                 return _mm_max_ps(_mm_set1_ps(f1), _mm_min_ps(_mm_set1_ps(f2), v0.xmm));
  515. #else
  516.                 float4 ret;
  517.                 ret.x = max(min(v0.x, f2), f1);
  518.                 ret.y = max(min(v0.y, f2), f1);
  519.                 ret.z = max(min(v0.z, f2), f1);
  520.                 ret.w = max(min(v0.w, f2), f1);
  521.                 return ret;
  522. #endif
  523.         }
  524.        
  525.         /* Clamp between vector values */
  526.         friend inline const float4 clamp(const float4& v0, const float4& v1, const float4& v2)
  527.         {
  528. #ifdef PLATFORM_SSE
  529.                 return _mm_max_ps(v1.xmm, _mm_min_ps(v2.xmm, v0.xmm));
  530. #else
  531.                 float4 ret;
  532.                 ret.x = max(min(v0.x, v2.x), v1.x);
  533.                 ret.y = max(min(v0.y, v2.y), v1.y);
  534.                 ret.z = max(min(v0.z, v2.z), v1.z);
  535.                 ret.w = max(min(v0.w, v2.w), v1.w);
  536.                 return ret;
  537. #endif
  538.         }
  539.        
  540.         /* Distance between two vectors */
  541.         friend inline float distance(const float4& v0, const float4& v1)
  542.         {      
  543. #ifdef PLATFORM_SSE4
  544.                 __m128 l = _mm_sub_ps(v0.xmm, v1.xmm);
  545.                 return _mm_cvtss_f32(_mm_sqrt_ss(_mm_dp_ps(l, l, 0xff)));
  546. #elif defined PLATFORM_SSE3
  547.                 __m128 l = _mm_sub_ps(v0.xmm, v1.xmm);
  548.                 l = _mm_mul_ps(l, l);
  549.                 l = _mm_hadd_ps(l, l);
  550.                 return _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(l, l)));          
  551. #elif defined PLATFORM_SSE
  552.                 __m128 l = _mm_sub_ps(v0.xmm, v1.xmm); 
  553.                 l = _mm_mul_ps(l, l);  
  554.                 l = _mm_add_ps(l, _mm_shuffle_ps(l, l, 0x4E)); 
  555.                 return _mm_cvtss_f32(_mm_sqrt_ss(_mm_add_ss(l, _mm_shuffle_ps(l, l, 0x11))));  
  556. #else  
  557.                 float4 v = v0 - v1;
  558.                 return sqrtf(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
  559. #endif
  560.         }              
  561.        
  562.         /* Dot product */
  563.         friend inline float dot(const float4 &v0, const float4 &v1)
  564.         {
  565. #ifdef PLATFORM_SSE4
  566.                 return _mm_cvtss_f32(_mm_dp_ps(v0.xmm, v1.xmm, 0xff));
  567. #elif defined PLATFORM_SSE3
  568.                 __m128 l = _mm_sub_ps(v0.xmm, v1.xmm);
  569.                 l = _mm_mul_ps(l, l);
  570.                 l = _mm_hadd_ps(l, l);
  571.                 return _mm_cvtss_f32(_mm_hadd_ps(l, l));
  572. #elif defined PLATFORM_SSE
  573.                 __m128 l = _mm_mul_ps(v0.xmm, v1.xmm);
  574.                 l = _mm_add_ps(l, _mm_shuffle_ps(l, l, 0x4E));
  575.                 return _mm_cvtss_f32(_mm_add_ss(l, _mm_shuffle_ps(l, l, 0x11)));
  576. #else
  577.                 return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z + v0.w * v1.w;  
  578. #endif
  579.         }
  580.        
  581.         /* Cross product */
  582.         friend float4 cross(const float4& v0, const float4& v1)
  583.         {
  584. #ifdef PLATFORM_SSE
  585.                 const __m128 l  = _mm_mul_ps(_mm_shuffle_ps(v0.xmm, v0.xmm, _MM_SHUFFLE(3, 0, 2, 1)), _mm_shuffle_ps(v1.xmm, v1.xmm, _MM_SHUFFLE(3, 1, 0, 2)));
  586.                 const __m128 r = _mm_mul_ps(_mm_shuffle_ps(v0.xmm, v0.xmm, _MM_SHUFFLE(3, 1, 0, 2)), _mm_shuffle_ps(v1.xmm, v1.xmm, _MM_SHUFFLE(3, 0, 2, 1)));
  587.                 return _mm_sub_ps(l, r);
  588. #else
  589.                 float4 ret;
  590.                 ret.x = v0.y * v1.z - v0.z * v1.y;
  591.                 ret.y = v0.z * v1.x - v0.x * v1.z;
  592.                 ret.z = v0.x * v1.y - v0.y * v1.x;
  593.                 ret.w = 0.0f;
  594.                 return ret;
  595. #endif
  596.         }
  597.        
  598.         /* Length of vector */
  599.         friend inline float length(const float4& v)
  600.         {              
  601. #ifdef PLATFORM_SSE4
  602.                 return _mm_cvtss_f32(_mm_sqrt_ss(_mm_dp_ps(v.xmm, v.xmm, 0xff)));
  603. #elif defined PLATFORM_SSE3
  604.                 __m128 l = _mm_mul_ps(v.xmm, v.xmm);
  605.                 l = _mm_hadd_ps(l, l);
  606.                 return _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(l, l)));          
  607. #elif defined PLATFORM_SSE
  608.                 __m128 l = _mm_mul_ps(v.xmm, v.xmm);
  609.                 l = _mm_add_ps(l, _mm_shuffle_ps(l, l, 0x4E)); 
  610.                 return _mm_cvtss_f32(_mm_sqrt_ss(_mm_add_ss(l, _mm_shuffle_ps(l, l, 0x11))));  
  611. #else  
  612.                 return sqrtf(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
  613. #endif
  614.         }      
  615.        
  616.         /* Normalization */
  617.         friend inline const float4 normalize(const float4& v)
  618.         {      
  619. #ifdef PLATFORM_SSE4
  620.                 return _mm_div_ps(v.xmm, _mm_sqrt_ps(_mm_dp_ps(v.xmm, v.xmm, 0xff)));
  621. #elif defined PLATFORM_SSE3
  622.                 __m128 l = _mm_mul_ps(v.xmm, v.xmm);
  623.                 l = _mm_hadd_ps(l, l);
  624.                 return _mm_div_ps(v.xmm, _mm_sqrt_ps(_mm_hadd_ps(l, l)));
  625. #elif defined PLATFORM_SSE
  626.                 __m128 l = _mm_mul_ps(v.xmm, v.xmm);           
  627.                 l = _mm_add_ps(l, _mm_shuffle_ps(l, l, 0x4E));         
  628.                 return _mm_mul_ps(v.xmm, _mm_rsqrt_ps(_mm_add_ps(l, _mm_shuffle_ps(l, l, 0x11))));
  629. #else  
  630.                 float l = 1.0f / sqrtf(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
  631.                 float4 ret;
  632.                 ret.x = v.x * l;
  633.                 ret.y = v.y * l;
  634.                 ret.z = v.z * l;
  635.                 ret.w = v.w * l;
  636.                 return ret;
  637. #endif
  638.         }              
  639.        
  640.         ALIGNED_NEW_DELETE
  641. };
  642.  
  643. #endif