Skip to content

Commit

Permalink
Merge pull request #500 from ulteq/ApproxMathRevert
Browse files Browse the repository at this point in the history
[Codechange] Reverted the approx_inv function
  • Loading branch information
Petr Ohlídal committed Dec 29, 2015
2 parents 9cdb194 + 8264952 commit d6c3161
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 33 deletions.
47 changes: 21 additions & 26 deletions source/main/physics/ApproxMath.h
Expand Up @@ -25,7 +25,7 @@ along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.

#pragma once
#ifndef __APPROXMATH_H_
#define __APPROXMATH_H_
#define __APPROXMATH_H_

#include "RoRPrerequisites.h"

Expand Down Expand Up @@ -69,16 +69,16 @@ inline float frand_11()

// Calculates approximate e^x.
// Use it in code not requiring precision
inline float approx_exp (const float x)
inline float approx_exp(const float x)
{
if (x < -15)
return 0.f ;
else if (x > 88)
return 1e38f ;
else {
int i=12102203*x+1064652319;
return *(float *)&i;
}
if (x < -15)
return 0.f ;
else if (x > 88)
return 1e38f ;
else {
int i=12102203*x+1064652319;
return *(float *)&i;
}
}

// Calculates approximate 2^x
Expand Down Expand Up @@ -113,17 +113,12 @@ inline float approx_sqrt(const float y)
// Calculates approximate 1/square_root(x)
// it is faster than fast_invSqrt BUT
// use it in code not requiring precision
inline float approx_invSqrt(float x)
inline float approx_invSqrt(const float y)
{
float xhalf = 0.5f*x;
int i = *(int*)&x; // get bits for floating value
i = 0x5f3759df - (i >> 1); // give initial guess y0
x = *(float*)&i; // convert bits back to float
x *= 1.5f - xhalf*x*x; // newton step, repeating this step
// increases accuracy
//x *= 1.5f - xhalf*x*x;

return x;
float f = y;
int i = 0x5f3759df - ( (*(int *)&f) >> 1);

return *(float *)&i;
}

// This function is a classic 1/square_root(x)code
Expand All @@ -143,33 +138,33 @@ inline float fast_invSqrt(const float v)
// It calculates a fast and accurate square_root(x)
inline float fast_sqrt(const float x)
{
return x * fast_invSqrt(x);
return x * fast_invSqrt(x);
}

inline float sign(const float x)
{
return (x > 0.0f) ? 1.0f : (x < 0.0f) ? -1.0f : 0.0f;
return (x > 0.0f) ? 1.0f : (x < 0.0f) ? -1.0f : 0.0f;
}

// Ogre3 specific helpers
inline Ogre::Vector3 approx_normalise(Ogre::Vector3 v)
{
return v*approx_invSqrt(v.squaredLength());
return v*approx_invSqrt(v.squaredLength());
}

inline Ogre::Vector3 fast_normalise(Ogre::Vector3 v)
{
return v*fast_invSqrt(v.squaredLength());
return v*fast_invSqrt(v.squaredLength());
}

inline float approx_length(Ogre::Vector3 v)
{
return approx_sqrt(v.squaredLength());
return approx_sqrt(v.squaredLength());
}

inline float fast_length(Ogre::Vector3 v)
{
return fast_sqrt(v.squaredLength());
return fast_sqrt(v.squaredLength());
}

#endif // __APPROXMATH_H_
12 changes: 5 additions & 7 deletions source/main/physics/flex/FlexBody.cpp
Expand Up @@ -944,7 +944,7 @@ bool FlexBody::flexitPrepare(Beam* b)
{
Vector3 diffX = m_nodes[m_node_x].smoothpos - m_nodes[m_node_center].smoothpos;
Vector3 diffY = m_nodes[m_node_y].smoothpos - m_nodes[m_node_center].smoothpos;
flexit_normal = approx_normalise(diffY.crossProduct(diffX));
flexit_normal = fast_normalise(diffY.crossProduct(diffX));

flexit_center = m_nodes[m_node_center].smoothpos + m_center_offset.x*diffX + m_center_offset.y*diffY;
flexit_center += m_center_offset.z*flexit_normal;
Expand All @@ -959,13 +959,11 @@ bool FlexBody::flexitPrepare(Beam* b)

void FlexBody::flexitCompute()
{
// If something unexpected happens here, then
// replace approx_normalise(a) with a.normalisedCopy()
for (int i=0; i<(int)m_vertex_count; i++)
{
Vector3 diffX = m_nodes[m_locators[i].nx].smoothpos - m_nodes[m_locators[i].ref].smoothpos;
Vector3 diffY = m_nodes[m_locators[i].ny].smoothpos - m_nodes[m_locators[i].ref].smoothpos;
Vector3 nCross = approx_normalise(diffX.crossProduct(diffY)); //nCross.normalise();
Vector3 nCross = fast_normalise(diffX.crossProduct(diffY)); //nCross.normalise();

m_dst_pos[i].x = diffX.x * m_locators[i].coords.x + diffY.x * m_locators[i].coords.y + nCross.x * m_locators[i].coords.z;
m_dst_pos[i].y = diffX.y * m_locators[i].coords.x + diffY.y * m_locators[i].coords.y + nCross.y * m_locators[i].coords.z;
Expand All @@ -977,7 +975,7 @@ void FlexBody::flexitCompute()
m_dst_normals[i].y = diffX.y * m_src_normals[i].x + diffY.y * m_src_normals[i].y + nCross.y * m_src_normals[i].z;
m_dst_normals[i].z = diffX.z * m_src_normals[i].x + diffY.z * m_src_normals[i].y + nCross.z * m_src_normals[i].z;

m_dst_normals[i] = approx_normalise(m_dst_normals[i]);
m_dst_normals[i] = fast_normalise(m_dst_normals[i]);
}
#if 0
for (int i=0; i<(int)m_vertex_count; i++)
Expand All @@ -988,10 +986,10 @@ void FlexBody::flexitCompute()

mat.SetColumn(0, diffX);
mat.SetColumn(1, diffY);
mat.SetColumn(2, approx_normalise(diffX.crossProduct(diffY))); // Old version: mat.SetColumn(2, m_nodes[loc.nz].smoothpos-m_nodes[loc.ref].smoothpos);
mat.SetColumn(2, fast_normalise(diffX.crossProduct(diffY))); // Old version: mat.SetColumn(2, m_nodes[loc.nz].smoothpos-m_nodes[loc.ref].smoothpos);

m_dst_pos[i] = mat * m_locators[i].coords + m_nodes[m_locators[i].ref].smoothpos - flexit_center;
m_dst_normals[i] = approx_normalise(mat * m_src_normals[i]);
m_dst_normals[i] = fast_normalise(mat * m_src_normals[i]);
}
#endif
}
Expand Down

0 comments on commit d6c3161

Please sign in to comment.