Rotate targetting reticule to mob. Add pivot point
Notion of pivot point now for rotating, i.e. the anchor point at which rotations are applied. Rotating the reticule is done by using inverse trigonometry, namely atan2f.
This commit is contained in:
parent
358f850a2c
commit
a43102ee26
Binary file not shown.
20
src/Debug.c
20
src/Debug.c
@ -147,7 +147,7 @@ INTERNAL void updateAndRenderDebugStack(Renderer *renderer, MemoryArena *arena,
|
||||
v4 color = V4(0, 0, 0, 1);
|
||||
renderer_staticString(renderer, arena, &GLOBAL_debug.font,
|
||||
GLOBAL_debug.debugStrings[i],
|
||||
GLOBAL_debug.currStringP, rotate, color);
|
||||
GLOBAL_debug.currStringP, V2(0, 0), rotate, color);
|
||||
GLOBAL_debug.currStringP.y -= (0.9f * GLOBAL_debug.stringLineGap);
|
||||
}
|
||||
|
||||
@ -179,7 +179,7 @@ INTERNAL void renderConsole(Renderer *renderer, MemoryArena *arena)
|
||||
v4 color = V4(0, 0, 0, 1);
|
||||
renderer_staticString(renderer, arena, &GLOBAL_debug.font,
|
||||
GLOBAL_debug.console[i], consoleStrP,
|
||||
rotate, color);
|
||||
V2(0, 0), rotate, color);
|
||||
consoleStrP.y -= (0.9f * GLOBAL_debug.stringLineGap);
|
||||
}
|
||||
}
|
||||
@ -218,7 +218,7 @@ void debug_drawUi(GameState *state, f32 dt)
|
||||
v2 strPos = V2((renderer->size.w * 0.5f) - (strLenInPixels * 0.5f),
|
||||
renderer->size.h - 300.0f);
|
||||
renderer_staticString(&state->renderer, &state->arena, font, battleStr,
|
||||
strPos, 0, color);
|
||||
strPos, V2(0, 0), 0, color);
|
||||
}
|
||||
|
||||
for (i32 i = 0; i < world->freeEntityIndex; i++)
|
||||
@ -257,7 +257,7 @@ void debug_drawUi(GameState *state, f32 dt)
|
||||
strPos.y += font->charMetrics[indexOfLowerAInMetrics].offset.y;
|
||||
|
||||
renderer_string(&state->renderer, &state->arena, cameraBounds, font,
|
||||
debugString, strPos, 0, color);
|
||||
debugString, strPos, V2(0, 0), 0, color);
|
||||
|
||||
f32 stringLineGap = 1.1f * asset_getVFontSpacing(font->metrics);
|
||||
strPos.y -= GLOBAL_debug.stringLineGap;
|
||||
@ -266,14 +266,14 @@ void debug_drawUi(GameState *state, f32 dt)
|
||||
snprintf(entityPosStr, ARRAY_COUNT(entityPosStr), "%06.2f, %06.2f",
|
||||
entity->pos.x, entity->pos.y);
|
||||
renderer_string(&state->renderer, &state->arena, cameraBounds, font,
|
||||
entityPosStr, strPos, 0, color);
|
||||
entityPosStr, strPos, V2(0, 0), 0, color);
|
||||
|
||||
strPos.y -= GLOBAL_debug.stringLineGap;
|
||||
char entityIDStr[32];
|
||||
snprintf(entityIDStr, ARRAY_COUNT(entityIDStr), "ID: %4d/%d", entity->id,
|
||||
world->uniqueIdAccumulator-1);
|
||||
renderer_string(&state->renderer, &state->arena, cameraBounds, font,
|
||||
entityIDStr, strPos, 0, color);
|
||||
entityIDStr, strPos, V2(0, 0), 0, color);
|
||||
|
||||
if (entity->stats)
|
||||
{
|
||||
@ -282,27 +282,27 @@ void debug_drawUi(GameState *state, f32 dt)
|
||||
snprintf(entityHealth, ARRAY_COUNT(entityHealth), "HP: %3.0f/%3.0f",
|
||||
entity->stats->health, entity->stats->maxHealth);
|
||||
renderer_string(&state->renderer, &state->arena, cameraBounds,
|
||||
font, entityHealth, strPos, 0, color);
|
||||
font, entityHealth, strPos, V2(0, 0), 0, color);
|
||||
|
||||
strPos.y -= GLOBAL_debug.stringLineGap;
|
||||
char entityTimer[32];
|
||||
snprintf(entityTimer, ARRAY_COUNT(entityTimer), "ATB: %3.0f/%3.0f",
|
||||
entity->stats->actionTimer, entity->stats->actionRate);
|
||||
renderer_string(&state->renderer, &state->arena, cameraBounds,
|
||||
font, entityTimer, strPos, 0, color);
|
||||
font, entityTimer, strPos, V2(0, 0), 0, color);
|
||||
|
||||
strPos.y -= GLOBAL_debug.stringLineGap;
|
||||
char entityIdTarget[32];
|
||||
snprintf(entityIdTarget, ARRAY_COUNT(entityIdTarget),
|
||||
"Targetting ID: %d", entity->stats->entityIdToAttack);
|
||||
renderer_string(&state->renderer, &state->arena, cameraBounds,
|
||||
font, entityIdTarget, strPos, 0, color);
|
||||
font, entityIdTarget, strPos, V2(0, 0), 0, color);
|
||||
}
|
||||
|
||||
strPos.y -= GLOBAL_debug.stringLineGap;
|
||||
char *entityStateStr = debug_entitystate_string(entity->state);
|
||||
renderer_string(&state->renderer, &state->arena, cameraBounds, font,
|
||||
entityStateStr, strPos, 0, color);
|
||||
entityStateStr, strPos, V2(0, 0), 0, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,20 +87,16 @@ createDefaultTexQuad(Renderer *renderer, RenderTex renderTex)
|
||||
return result;
|
||||
}
|
||||
|
||||
INTERNAL void renderObject(Renderer *renderer, v2 pos, v2 size, f32 rotate,
|
||||
v4 color, Texture *tex)
|
||||
INTERNAL void renderObject(Renderer *renderer, v2 pos, v2 size, v2 pivotPoint,
|
||||
f32 rotate, v4 color, Texture *tex)
|
||||
{
|
||||
mat4 transMatrix = mat4_translate(pos.x, pos.y, 0.0f);
|
||||
// NOTE(doyle): Rotate from the center of the object, not its' origin (i.e.
|
||||
// top left)
|
||||
mat4 rotateMatrix = mat4_translate((size.x * 0.5f), (size.y * 0.5f), 0.0f);
|
||||
// NOTE(doyle): Rotate from pivot point of the object, (0, 0) is top left
|
||||
mat4 rotateMatrix = mat4_translate(pivotPoint.x, pivotPoint.y, 0.0f);
|
||||
rotateMatrix = mat4_mul(rotateMatrix, mat4_rotate(rotate, 0.0f, 0.0f, 1.0f));
|
||||
rotateMatrix = mat4_mul(rotateMatrix, mat4_translate((size.x * -0.5f), (size.y * -0.5f), 0.0f));
|
||||
rotateMatrix = mat4_mul(rotateMatrix, mat4_translate(-pivotPoint.x, -pivotPoint.y, 0.0f));
|
||||
|
||||
// NOTE(doyle): We draw everything as a unit square in OGL. Scale it to size
|
||||
// TODO(doyle): We should have a notion of hitbox size and texture size
|
||||
// we're going to render so we can draw textures that may be bigger than the
|
||||
// entity, (slightly) but keep a consistent bounding box
|
||||
mat4 scaleMatrix = mat4_scale(size.x, size.y, 1.0f);
|
||||
mat4 model = mat4_mul(transMatrix, mat4_mul(rotateMatrix, scaleMatrix));
|
||||
|
||||
@ -140,7 +136,7 @@ INTERNAL void renderObject(Renderer *renderer, v2 pos, v2 size, f32 rotate,
|
||||
}
|
||||
|
||||
void renderer_rect(Renderer *const renderer, v4 cameraBounds, v2 pos, v2 size,
|
||||
f32 rotate, RenderTex renderTex, v4 color)
|
||||
v2 pivotPoint, f32 rotate, RenderTex renderTex, v4 color)
|
||||
{
|
||||
RenderQuad quad = createDefaultTexQuad(renderer, renderTex);
|
||||
updateBufferObject(renderer, &quad, 1);
|
||||
@ -148,13 +144,14 @@ void renderer_rect(Renderer *const renderer, v4 cameraBounds, v2 pos, v2 size,
|
||||
// NOTE(doyle): Get the origin of cameraBounds in world space, bottom left
|
||||
v2 offsetFromCamOrigin = V2(cameraBounds.x, cameraBounds.w);
|
||||
v2 rectRelativeToCamera = v2_sub(pos, offsetFromCamOrigin);
|
||||
renderObject(renderer, rectRelativeToCamera, size, rotate, color,
|
||||
renderTex.tex);
|
||||
renderObject(renderer, rectRelativeToCamera, size, pivotPoint, rotate,
|
||||
color, renderTex.tex);
|
||||
}
|
||||
|
||||
void renderer_string(Renderer *const renderer, MemoryArena *arena,
|
||||
v4 cameraBounds, Font *const font,
|
||||
const char *const string, v2 pos, f32 rotate, v4 color)
|
||||
const char *const string, v2 pos, v2 pivotPoint,
|
||||
f32 rotate, v4 color)
|
||||
{
|
||||
i32 strLen = common_strlen(string);
|
||||
// TODO(doyle): Scale, not too important .. but rudimentary infrastructure
|
||||
@ -208,14 +205,14 @@ void renderer_string(Renderer *const renderer, MemoryArena *arena,
|
||||
// relative to the window size, hence we also render at the origin since
|
||||
// we're rendering a window sized buffer
|
||||
updateBufferObject(renderer, stringQuads, quadIndex);
|
||||
renderObject(renderer, V2(0.0f, 0.0f), renderer->size, rotate, color,
|
||||
font->tex);
|
||||
renderObject(renderer, V2(0.0f, 0.0f), renderer->size, pivotPoint,
|
||||
rotate, color, font->tex);
|
||||
PLATFORM_MEM_FREE(arena, stringQuads, strLen * sizeof(RenderQuad));
|
||||
}
|
||||
}
|
||||
|
||||
void renderer_entity(Renderer *renderer, v4 cameraBounds, Entity *entity,
|
||||
f32 rotate, v4 color)
|
||||
v2 pivotPoint, f32 rotate, v4 color)
|
||||
{
|
||||
// TODO(doyle): Batch into render groups
|
||||
|
||||
@ -247,6 +244,6 @@ void renderer_entity(Renderer *renderer, v4 cameraBounds, Entity *entity,
|
||||
v2 entityRelativeToCamera = v2_sub(entity->pos, offsetFromCamOrigin);
|
||||
|
||||
renderObject(renderer, entityRelativeToCamera, entity->renderSize,
|
||||
rotate, color, entity->tex);
|
||||
pivotPoint, rotate, color, entity->tex);
|
||||
}
|
||||
}
|
||||
|
@ -1022,7 +1022,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
||||
*/
|
||||
updateEntityAnim(entity, dt);
|
||||
/* Calculate region to render */
|
||||
renderer_entity(renderer, cameraBounds, entity, 0, V4(1, 1, 1, 1));
|
||||
renderer_entity(renderer, cameraBounds, entity, V2(0, 0), 0, V4(1, 1, 1, 1));
|
||||
}
|
||||
|
||||
// TODO(doyle): Dead hero not accounted for here
|
||||
@ -1060,8 +1060,8 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
||||
V2(10.0f, (renderer->size.h * 0.5f) - (0.5f * heroAvatarSize.h));
|
||||
|
||||
RenderTex heroRenderTex = {hero->tex, heroAvatarTexRect};
|
||||
renderer_staticRect(renderer, heroAvatarP, heroAvatarSize, 0, heroRenderTex,
|
||||
V4(1, 1, 1, 1));
|
||||
renderer_staticRect(renderer, heroAvatarP, heroAvatarSize, V2(0, 0), 0,
|
||||
heroRenderTex, V4(1, 1, 1, 1));
|
||||
|
||||
char heroAvatarStr[20];
|
||||
snprintf(heroAvatarStr, ARRAY_COUNT(heroAvatarStr), "HP: %3.0f/%3.0f",
|
||||
@ -1070,36 +1070,42 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
||||
CAST(f32)(font->maxSize.w * common_strlen(heroAvatarStr));
|
||||
v2 strPos = V2(heroAvatarP.x, heroAvatarP.y - (0.5f * heroAvatarSize.h));
|
||||
renderer_staticString(&state->renderer, &state->arena, font, heroAvatarStr,
|
||||
strPos, 0, V4(0, 0, 1, 1));
|
||||
strPos, V2(0, 0), 0, V4(0, 0, 1, 1));
|
||||
|
||||
#ifdef DENGINE_DEBUG
|
||||
ASSERT(world->numEntitiesInBattle != 1);
|
||||
#endif
|
||||
if (world->numEntitiesInBattle > 1)
|
||||
{
|
||||
for (i32 i = 0; i < world->maxEntities; i++)
|
||||
{
|
||||
Entity entity = world->entities[i];
|
||||
if (entity.id == hero->id) continue;
|
||||
Entity *entity = &world->entities[i];
|
||||
if (entity->id == hero->id)
|
||||
continue;
|
||||
|
||||
|
||||
f32 distance = v2_magnitude(hero->pos, entity.pos);
|
||||
if (entity.state == entitystate_battle)
|
||||
if (entity->state == entitystate_attack ||
|
||||
entity->state == entitystate_battle)
|
||||
{
|
||||
Texture *emptyTex =
|
||||
asset_getTexture(assetManager, texlist_empty);
|
||||
v2 heroCenter =
|
||||
v2_add(hero->pos, v2_scale(hero->hitboxSize, 0.5f));
|
||||
RenderTex renderTex = {emptyTex, V4(0, 1, 1, 0)};
|
||||
renderer_rect(&state->renderer, cameraBounds, heroCenter,
|
||||
V2(distance, 5.0f), 0, renderTex,
|
||||
V4(1, 0, 0, 0.5f));
|
||||
}
|
||||
}
|
||||
}
|
||||
v2 difference = v2_sub(entity->pos, hero->pos);
|
||||
f32 angle = math_atan2f(difference.y, difference.x);
|
||||
f32 angleDegrees = RADIANS_TO_DEGREES(angle);
|
||||
|
||||
Texture *emptyTex = asset_getTexture(assetManager, texlist_empty);
|
||||
v2 heroCenter = v2_add(hero->pos, v2_scale(hero->hitboxSize, 0.5f));
|
||||
RenderTex renderTex = {emptyTex, V4(0, 1, 1, 0)};
|
||||
f32 distance = v2_magnitude(hero->pos, entity->pos);
|
||||
renderer_rect(&state->renderer, cameraBounds, heroCenter,
|
||||
V2(distance, 2.0f), V2(0, 0), angle, renderTex,
|
||||
V4(1, 0, 0, 1.0f));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DENGINE_DEBUG
|
||||
renderer_rect(&state->renderer, cameraBounds, V2(500, 500), V2(100, 2.0f),
|
||||
V2(0, 0), DEGREES_TO_RADIANS(0.0f), renderTex,
|
||||
V4(0, 0, 1, 1.0f));
|
||||
renderer_rect(&state->renderer, cameraBounds, V2(500, 500), V2(100, 2.0f),
|
||||
V2(0, 0), DEGREES_TO_RADIANS(5.0f), renderTex,
|
||||
V4(0, 0, 1, 1.0f));
|
||||
renderer_rect(&state->renderer, cameraBounds, V2(500, 500), V2(100, 2.0f),
|
||||
V2(0, 0), DEGREES_TO_RADIANS(90.0f), renderTex,
|
||||
V4(0, 0, 1, 1.0f));
|
||||
debug_drawUi(state, dt);
|
||||
#endif
|
||||
}
|
||||
|
@ -8,8 +8,21 @@
|
||||
#define SQUARED(x) (x * x)
|
||||
#define ABS(x) ((x) > 0 ? (x) : -(x))
|
||||
#define DEGREES_TO_RADIANS(x) (x * (MATH_PI / 180.0f))
|
||||
#define RADIANS_TO_DEGREES(x) (x * (180.0f / MATH_PI))
|
||||
#define SQRT(x) (sqrtf(x))
|
||||
|
||||
INTERNAL inline f32 math_acosf(f32 a)
|
||||
{
|
||||
f32 result = acosf(a);
|
||||
return result;
|
||||
}
|
||||
|
||||
INTERNAL inline f32 math_atan2f(f32 y, f32 x)
|
||||
{
|
||||
f32 result = atan2f(y, x);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* VECTORS */
|
||||
typedef union v2
|
||||
{
|
||||
@ -120,12 +133,26 @@ DEFINE_VECTOR_FLOAT_MATH(2);
|
||||
DEFINE_VECTOR_FLOAT_MATH(3);
|
||||
DEFINE_VECTOR_FLOAT_MATH(4);
|
||||
|
||||
INTERNAL inline f32 v2_magnitude(const v2 a, const v2 b)
|
||||
INTERNAL inline f32 v2_lengthSq(const v2 a, const v2 b)
|
||||
{
|
||||
f32 x = b.x - a.x;
|
||||
f32 y = b.y - a.y;
|
||||
f32 inner = (SQUARED(x) + SQUARED(y));
|
||||
f32 result = SQRT(inner);
|
||||
f32 result = (SQUARED(x) + SQUARED(y));
|
||||
return result;
|
||||
}
|
||||
|
||||
INTERNAL inline f32 v2_magnitude(const v2 a, const v2 b)
|
||||
{
|
||||
f32 lengthSq = v2_lengthSq(a, b);
|
||||
f32 result = SQRT(lengthSq);
|
||||
return result;
|
||||
}
|
||||
|
||||
INTERNAL inline v2 v2_normalise(const v2 a)
|
||||
{
|
||||
f32 magnitude = v2_magnitude(V2(0, 0), a);
|
||||
v2 result = V2(a.x, a.y);
|
||||
result = v2_scale(a, 1 / magnitude);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -27,30 +27,32 @@ typedef struct RenderTex
|
||||
// TODO(doyle): Clean up lines
|
||||
// Renderer::~Renderer() { glDeleteVertexArrays(1, &this->quadVAO); }
|
||||
void renderer_rect(Renderer *const renderer, v4 cameraBounds, v2 pos, v2 size,
|
||||
f32 rotate, RenderTex renderTex, v4 color);
|
||||
v2 pivotPoint, f32 rotate, RenderTex renderTex, v4 color);
|
||||
|
||||
inline void renderer_staticRect(Renderer *const renderer, v2 pos, v2 size,
|
||||
f32 rotate, RenderTex renderTex, v4 color)
|
||||
v2 pivotPoint, f32 rotate, RenderTex renderTex,
|
||||
v4 color)
|
||||
{
|
||||
v4 staticCameraBounds = math_getRect(V2(0, 0), renderer->size);
|
||||
renderer_rect(renderer, staticCameraBounds, pos, size, rotate, renderTex,
|
||||
color);
|
||||
renderer_rect(renderer, staticCameraBounds, pos, size, pivotPoint, rotate,
|
||||
renderTex, color);
|
||||
}
|
||||
|
||||
void renderer_string(Renderer *const renderer, MemoryArena *arena,
|
||||
v4 cameraBounds, Font *const font,
|
||||
const char *const string, v2 pos, f32 rotate, v4 color);
|
||||
const char *const string, v2 pos, v2 pivotPoint,
|
||||
f32 rotate, v4 color);
|
||||
|
||||
inline void renderer_staticString(Renderer *const renderer, MemoryArena *arena,
|
||||
Font *const font, const char *const string,
|
||||
v2 pos, f32 rotate, v4 color)
|
||||
v2 pos, v2 pivotPoint, f32 rotate, v4 color)
|
||||
{
|
||||
v4 staticCameraBounds = math_getRect(V2(0, 0), renderer->size);
|
||||
renderer_string(renderer, arena, staticCameraBounds, font, string, pos,
|
||||
rotate, color);
|
||||
pivotPoint, rotate, color);
|
||||
}
|
||||
|
||||
void renderer_entity(Renderer *renderer, v4 cameraBounds, Entity *entity,
|
||||
f32 rotate, v4 color);
|
||||
v2 pivotPoint, f32 rotate, v4 color);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user