diff --git a/programs/testSDL.c b/programs/testSDL.c index b38d8af..4349c71 100644 --- a/programs/testSDL.c +++ b/programs/testSDL.c @@ -309,6 +309,13 @@ void draw() int main() { + + +for (int i = -512; i < 513; ++i) + printf("%d: %d (%d)\n",i,S3L_asin(i),S3L_sin(S3L_asin(i))); + +return 0; + SDL_Window *window = SDL_CreateWindow("test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, S3L_RESOLUTION_X, S3L_RESOLUTION_Y, SDL_WINDOW_SHOWN); SDL_Renderer *renderer = SDL_CreateRenderer(window,-1,0); SDL_Texture *texture = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGBX8888, SDL_TEXTUREACCESS_STATIC, S3L_RESOLUTION_X, S3L_RESOLUTION_Y); @@ -446,6 +453,9 @@ S3L_setTransform3D(3196,1814,5958,-18,300,0,512,512,512,&(scene.camera.transform if (keys['g']) scene.camera.transform.rotation.z += 1; + if (keys['p']) + S3L_lookAt(scene.camera.transform.translation,scene.models[1].transform.translation,&(scene.camera.transform)); + SDL_RenderClear(renderer); SDL_RenderCopy(renderer,texture,NULL,NULL); SDL_RenderPresent(renderer); diff --git a/small3dlib.h b/small3dlib.h index 74e09c2..f4f9c03 100644 --- a/small3dlib.h +++ b/small3dlib.h @@ -280,6 +280,8 @@ static inline void S3L_vec3Add(S3L_Vec4 *result, S3L_Vec4 added); static inline void S3L_vec3Sub(S3L_Vec4 *result, S3L_Vec4 substracted); S3L_Unit S3L_vec3Length(S3L_Vec4 v); void S3L_normalizeVec3(S3L_Vec4 *v); +S3L_Unit S3L_vec2Length(S3L_Vec4 v); +void S3L_normalizeVec2(S3L_Vec4 *v); #define S3L_logVec4(v)\ printf("Vec4: %d %d %d %d\n",((v).x),((v).y),((v).z),((v).w)) @@ -302,6 +304,8 @@ typedef struct static inline void S3L_initTransoform3D(S3L_Transform3D *t); +void S3L_lookAt(S3L_Vec4 pointFrom, S3L_Vec4 pointTo, S3L_Transform3D *t); + void S3L_setTransform3D( S3L_Unit tx, S3L_Unit ty, @@ -439,10 +443,12 @@ static inline void S3L_initPixelInfo(S3L_PixelInfo *p); static inline S3L_Unit S3L_abs(S3L_Unit value); static inline S3L_Unit S3L_min(S3L_Unit v1, S3L_Unit v2); static inline S3L_Unit S3L_max(S3L_Unit v1, S3L_Unit v2); +static inline S3L_Unit S3L_clamp(S3L_Unit v, S3L_Unit v1, S3L_Unit v2); static inline S3L_Unit S3L_wrap(S3L_Unit value, S3L_Unit mod); static inline S3L_Unit S3L_nonZero(S3L_Unit value); S3L_Unit S3L_sin(S3L_Unit x); +S3L_Unit S3L_asin(S3L_Unit x); static inline S3L_Unit S3L_cos(S3L_Unit x); S3L_Unit S3L_vec3Length(S3L_Vec4 v); @@ -639,6 +645,7 @@ static inline int8_t S3L_stencilTest( (S3L_COMPUTE_DEPTH && (S3L_PERSPECTIVE_CORRECTION != 1)) #define S3L_SIN_TABLE_LENGTH 128 + static const S3L_Unit S3L_sinTable[S3L_SIN_TABLE_LENGTH] = { /* 511 was chosen here as a highest number that doesn't overflow during @@ -808,6 +815,11 @@ S3L_Unit S3L_max(S3L_Unit v1, S3L_Unit v2) return v1 >= v2 ? v1 : v2; } +S3L_Unit S3L_clamp(S3L_Unit v, S3L_Unit v1, S3L_Unit v2) +{ + return v >= v1 ? (v <= v2 ? v : v2) : v1; +} + S3L_Unit S3L_wrap(S3L_Unit value, S3L_Unit mod) { return value >= 0 ? (value % mod) : (mod + (value % mod) - 1); @@ -888,6 +900,41 @@ S3L_Unit S3L_sin(S3L_Unit x) return positive ? S3L_sinTable[x] : -1 * S3L_sinTable[x]; } +S3L_Unit S3L_asin(S3L_Unit x) +{ + x = S3L_clamp(x,-S3L_FRACTIONS_PER_UNIT,S3L_FRACTIONS_PER_UNIT); + + int8_t sign = 1; + + if (x < 0) + { + sign = -1; + x *= -1; + } + + int16_t low = 0; + int16_t high = S3L_SIN_TABLE_LENGTH -1; + int16_t middle; + + while (low <= high) // binary search + { + middle = (low + high) / 2; + + S3L_Unit v = S3L_sinTable[middle]; + + if (v > x) + high = middle - 1; + else if (v < x) + low = middle + 1; + else + break; + } + + middle *= S3L_SIN_TABLE_UNIT_STEP; + + return sign * middle; +} + S3L_Unit S3L_cos(S3L_Unit x) { return S3L_sin(x - S3L_FRACTIONS_PER_UNIT / 4); @@ -1005,6 +1052,11 @@ S3L_Unit S3L_vec3Length(S3L_Vec4 v) return S3L_sqrt(v.x * v.x + v.y * v.y + v.z * v.z); } +S3L_Unit S3L_vec2Length(S3L_Vec4 v) +{ + return S3L_sqrt(v.x * v.x + v.y * v.y); +} + void S3L_normalizeVec3(S3L_Vec4 *v) { S3L_Unit l = S3L_vec3Length(*v); @@ -1017,6 +1069,17 @@ void S3L_normalizeVec3(S3L_Vec4 *v) v->z = (v->z * S3L_FRACTIONS_PER_UNIT) / l; } +void S3L_normalizeVec2(S3L_Vec4 *v) +{ + S3L_Unit l = S3L_vec2Length(*v); + + if (l == 0) + return; + + v->x = (v->x * S3L_FRACTIONS_PER_UNIT) / l; + v->y = (v->y * S3L_FRACTIONS_PER_UNIT) / l; +} + void S3L_initTransoform3D(S3L_Transform3D *t) { S3L_initVec4(&(t->translation)); @@ -1026,6 +1089,20 @@ void S3L_initTransoform3D(S3L_Transform3D *t) t->scale.z = S3L_FRACTIONS_PER_UNIT; } +void S3L_lookAt(S3L_Vec4 pointFrom, S3L_Vec4 pointTo, S3L_Transform3D *t) +{ + S3L_Vec4 v; + + v.x = pointTo.x - pointFrom.x; + v.y = pointTo.z - pointFrom.z; + + S3L_normalizeVec2(&v); + + t->rotation.y = (v.y + S3L_FRACTIONS_PER_UNIT) / 2 ; + + // TODO +} + void S3L_setTransform3D( S3L_Unit tx, S3L_Unit ty,