mirror of
https://git.coom.tech/drummyfish/small3dlib.git
synced 2024-11-20 20:29:58 +01:00
Add other sin method
This commit is contained in:
parent
da1b3914ca
commit
e4fa1a714f
1 changed files with 61 additions and 16 deletions
77
small3dlib.h
77
small3dlib.h
|
@ -10,7 +10,7 @@
|
|||
license: CC0 1.0 (public domain)
|
||||
found at https://creativecommons.org/publicdomain/zero/1.0/
|
||||
+ additional waiver of all IP
|
||||
version: 0.901d
|
||||
version: 0.902d
|
||||
|
||||
Before including the library, define S3L_PIXEL_FUNCTION to the name of the
|
||||
function you'll be using to draw single pixels (this function will be called
|
||||
|
@ -83,16 +83,6 @@
|
|||
vertical size (y) depends on the aspect ratio (S3L_RESOLUTION_X and
|
||||
S3L_RESOLUTION_Y). Camera FOV is defined by focal length in S3L_Units.
|
||||
|
||||
y ^
|
||||
| _
|
||||
| /| z
|
||||
____|_/__
|
||||
| |/ |
|
||||
-----[0,0,0]-|-----> x
|
||||
|____|____|
|
||||
|
|
||||
|
|
||||
|
||||
Rotations use Euler angles and are generally in the extrinsic Euler angles in
|
||||
ZXY order (by Z, then by X, then by Y). Positive rotation about an axis
|
||||
rotates CW (clock-wise) when looking in the direction of the axis.
|
||||
|
@ -180,6 +170,14 @@
|
|||
#define S3L_USE_WIDER_TYPES 0
|
||||
#endif
|
||||
|
||||
#ifndef S3L_SIN_METHOD
|
||||
/** Says which method should be used for computing sin/cos functions, possible
|
||||
values: 0 (lookup table, takes more program memory), 1 (Bhaskara's
|
||||
approximation, slower). This may cause the trigonometric functions give
|
||||
slightly different results. */
|
||||
#define S3L_SIN_METHOD 0
|
||||
#endif
|
||||
|
||||
/** Units of measurement in 3D space. There is S3L_FRACTIONS_PER_UNIT in one
|
||||
spatial unit. By dividing the unit into fractions we effectively achieve a
|
||||
fixed point arithmetic. The number of fractions is a constant that serves as
|
||||
|
@ -907,6 +905,7 @@ static inline int8_t S3L_stencilTest(
|
|||
|
||||
#define S3L_SIN_TABLE_LENGTH 128
|
||||
|
||||
#if S3L_SIN_METHOD == 0
|
||||
static const S3L_Unit S3L_sinTable[S3L_SIN_TABLE_LENGTH] =
|
||||
{
|
||||
/* 511 was chosen here as a highest number that doesn't overflow during
|
||||
|
@ -977,6 +976,7 @@ static const S3L_Unit S3L_sinTable[S3L_SIN_TABLE_LENGTH] =
|
|||
(510*S3L_FRACTIONS_PER_UNIT)/511, (510*S3L_FRACTIONS_PER_UNIT)/511,
|
||||
(510*S3L_FRACTIONS_PER_UNIT)/511, (510*S3L_FRACTIONS_PER_UNIT)/511
|
||||
};
|
||||
#endif
|
||||
|
||||
#define S3L_SIN_TABLE_UNIT_STEP\
|
||||
(S3L_FRACTIONS_PER_UNIT / (S3L_SIN_TABLE_LENGTH * 4))
|
||||
|
@ -1349,6 +1349,7 @@ void S3L_mat4Xmat4(S3L_Mat4 m1, S3L_Mat4 m2)
|
|||
|
||||
S3L_Unit S3L_sin(S3L_Unit x)
|
||||
{
|
||||
#if S3L_SIN_METHOD == 0
|
||||
x = S3L_wrap(x / S3L_SIN_TABLE_UNIT_STEP,S3L_SIN_TABLE_LENGTH * 4);
|
||||
int8_t positive = 1;
|
||||
|
||||
|
@ -1371,10 +1372,37 @@ S3L_Unit S3L_sin(S3L_Unit x)
|
|||
}
|
||||
|
||||
return positive ? S3L_sinTable[x] : -1 * S3L_sinTable[x];
|
||||
#else
|
||||
int8_t sign = 1;
|
||||
|
||||
if (x < 0) // odd function
|
||||
{
|
||||
x *= -1;
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
x %= S3L_FRACTIONS_PER_UNIT;
|
||||
|
||||
if (x > S3L_FRACTIONS_PER_UNIT / 2)
|
||||
{
|
||||
x -= S3L_FRACTIONS_PER_UNIT / 2;
|
||||
sign *= -1;
|
||||
}
|
||||
|
||||
S3L_Unit tmp = S3L_FRACTIONS_PER_UNIT - 2 * x;
|
||||
|
||||
#define _PI2 ((S3L_Unit) (9.8696044 * S3L_FRACTIONS_PER_UNIT))
|
||||
return sign * // Bhaskara's approximation
|
||||
(((32 * x * _PI2) / S3L_FRACTIONS_PER_UNIT) * tmp) /
|
||||
((_PI2 * (5 * S3L_FRACTIONS_PER_UNIT - (8 * x * tmp) /
|
||||
S3L_FRACTIONS_PER_UNIT)) / S3L_FRACTIONS_PER_UNIT);
|
||||
#undef _PI2
|
||||
#endif
|
||||
}
|
||||
|
||||
S3L_Unit S3L_asin(S3L_Unit x)
|
||||
{
|
||||
#if S3L_SIN_METHOD == 0
|
||||
x = S3L_clamp(x,-S3L_FRACTIONS_PER_UNIT,S3L_FRACTIONS_PER_UNIT);
|
||||
|
||||
int8_t sign = 1;
|
||||
|
@ -1385,9 +1413,7 @@ S3L_Unit S3L_asin(S3L_Unit x)
|
|||
x *= -1;
|
||||
}
|
||||
|
||||
int16_t low = 0;
|
||||
int16_t high = S3L_SIN_TABLE_LENGTH -1;
|
||||
int16_t middle;
|
||||
int16_t low = 0, high = S3L_SIN_TABLE_LENGTH -1, middle;
|
||||
|
||||
while (low <= high) // binary search
|
||||
{
|
||||
|
@ -1406,6 +1432,27 @@ S3L_Unit S3L_asin(S3L_Unit x)
|
|||
middle *= S3L_SIN_TABLE_UNIT_STEP;
|
||||
|
||||
return sign * middle;
|
||||
#else
|
||||
S3L_Unit low = -1 * S3L_FRACTIONS_PER_UNIT / 4,
|
||||
high = S3L_FRACTIONS_PER_UNIT / 4,
|
||||
middle;
|
||||
|
||||
while (low <= high) // binary search
|
||||
{
|
||||
middle = (low + high) / 2;
|
||||
|
||||
S3L_Unit v = S3L_sin(middle);
|
||||
|
||||
if (v > x)
|
||||
high = middle - 1;
|
||||
else if (v < x)
|
||||
low = middle + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return middle;
|
||||
#endif
|
||||
}
|
||||
|
||||
S3L_Unit S3L_cos(S3L_Unit x)
|
||||
|
@ -2244,7 +2291,6 @@ void S3L_drawTriangle(
|
|||
#endif
|
||||
|
||||
// draw the row -- inner loop:
|
||||
|
||||
for (S3L_ScreenCoord x = lXClipped; x < rXClipped; ++x)
|
||||
{
|
||||
int8_t testsPassed = 1;
|
||||
|
@ -2404,7 +2450,6 @@ if (_S3L_projectedTriangleState != 0)
|
|||
p.barycentric[2] = newBarycentric[2];
|
||||
}
|
||||
#endif
|
||||
|
||||
S3L_PIXEL_FUNCTION(&p);
|
||||
} // tests passed
|
||||
|
||||
|
|
Loading…
Reference in a new issue