Fixed camera
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
exec "config/init-base";
|
exec "config/init-base";
|
||||||
|
|
||||||
screen height 270;
|
|
||||||
screen height 270;
|
screen height 270;
|
||||||
|
|
||||||
bind ` toggleconsole;
|
bind ` toggleconsole;
|
||||||
|
@@ -98,6 +98,34 @@ void cameraPushMatrix(camera_t *camera) {
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT:
|
||||||
|
assertTrue(
|
||||||
|
camera->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE ||
|
||||||
|
camera->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED,
|
||||||
|
"Pixel perfect camera view requires perspective projection"
|
||||||
|
);
|
||||||
|
|
||||||
|
const float_t viewportHeight = (
|
||||||
|
(float_t)frameBufferGetHeight(FRAMEBUFFER_BOUND)
|
||||||
|
);
|
||||||
|
const float_t z = (viewportHeight / 2.0f) / (
|
||||||
|
camera->lookatPixelPerfect.pixelsPerUnit *
|
||||||
|
tanf(camera->perspective.fov / 2.0f)
|
||||||
|
);
|
||||||
|
|
||||||
|
vec3 position;
|
||||||
|
glm_vec3_copy(camera->lookatPixelPerfect.target, position);
|
||||||
|
glm_vec3_add(position, camera->lookatPixelPerfect.offset, position);
|
||||||
|
position[2] += z;
|
||||||
|
|
||||||
|
glm_lookat(
|
||||||
|
position,
|
||||||
|
camera->lookatPixelPerfect.target,
|
||||||
|
camera->lookatPixelPerfect.up,
|
||||||
|
view
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
case CAMERA_VIEW_TYPE_2D:
|
case CAMERA_VIEW_TYPE_2D:
|
||||||
glm_mat4_identity(view);
|
glm_mat4_identity(view);
|
||||||
glm_translate(view, (vec3){
|
glm_translate(view, (vec3){
|
||||||
|
@@ -20,7 +20,8 @@ typedef enum {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
CAMERA_VIEW_TYPE_MATRIX,
|
CAMERA_VIEW_TYPE_MATRIX,
|
||||||
CAMERA_VIEW_TYPE_LOOKAT,
|
CAMERA_VIEW_TYPE_LOOKAT,
|
||||||
CAMERA_VIEW_TYPE_2D
|
CAMERA_VIEW_TYPE_2D,
|
||||||
|
CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT
|
||||||
} cameraviewtype_t;
|
} cameraviewtype_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -36,6 +37,13 @@ typedef struct {
|
|||||||
float_t up[3];
|
float_t up[3];
|
||||||
} lookat;
|
} lookat;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
float_t offset[3];
|
||||||
|
float_t target[3];
|
||||||
|
float_t up[3];
|
||||||
|
float_t pixelsPerUnit;
|
||||||
|
} lookatPixelPerfect;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
float_t position[2];
|
float_t position[2];
|
||||||
float_t zoom;
|
float_t zoom;
|
||||||
|
@@ -81,36 +81,36 @@ void playerInteraction(entity_t *entity) {
|
|||||||
// Copy to max
|
// Copy to max
|
||||||
glm_vec2_copy(interactBox.min, interactBox.max);
|
glm_vec2_copy(interactBox.min, interactBox.max);
|
||||||
|
|
||||||
// Size of the hitbox
|
// // Size of the hitbox
|
||||||
vec2 halfSize = {
|
// vec2 halfSize = {
|
||||||
TILESET_ENTITIES.tileWidth * PLAYER_INTERACTION_SIZE * 0.5f,
|
// 1 * PLAYER_INTERACTION_SIZE * 0.5f,
|
||||||
TILESET_ENTITIES.tileHeight * PLAYER_INTERACTION_SIZE * 0.5f
|
// 1 * PLAYER_INTERACTION_SIZE * 0.5f
|
||||||
};
|
// };
|
||||||
|
|
||||||
// Subtract from min, add to max.
|
// // Subtract from min, add to max.
|
||||||
glm_vec2_sub(interactBox.min, halfSize, interactBox.min);
|
// glm_vec2_sub(interactBox.min, halfSize, interactBox.min);
|
||||||
glm_vec2_add(interactBox.max, halfSize, interactBox.max);
|
// glm_vec2_add(interactBox.max, halfSize, interactBox.max);
|
||||||
|
|
||||||
// For each entity
|
// // For each entity
|
||||||
entity_t *start = ENTITIES;
|
// entity_t *start = ENTITIES;
|
||||||
entity_t *end = &ENTITIES[ENTITY_COUNT];
|
// entity_t *end = &ENTITIES[ENTITY_COUNT];
|
||||||
vec2 otherSize = { TILESET_ENTITIES.tileWidth, TILESET_ENTITIES.tileHeight };
|
// vec2 otherSize = { 1, 1 };
|
||||||
physicsbox_t otherBox;
|
// physicsbox_t otherBox;
|
||||||
physicsboxboxresult_t result;
|
// physicsboxboxresult_t result;
|
||||||
|
|
||||||
do {
|
// do {
|
||||||
if(start->type != ENTITY_TYPE_NPC) continue;
|
// if(start->type != ENTITY_TYPE_NPC) continue;
|
||||||
|
|
||||||
// Setup other box.
|
// // Setup other box.
|
||||||
glm_vec2_copy(start->position, otherBox.min);
|
// glm_vec2_copy(start->position, otherBox.min);
|
||||||
glm_vec2_copy(start->position, otherBox.max);
|
// glm_vec2_copy(start->position, otherBox.max);
|
||||||
glm_vec2_sub(otherBox.min, otherSize, otherBox.min);
|
// glm_vec2_sub(otherBox.min, otherSize, otherBox.min);
|
||||||
glm_vec2_add(otherBox.min, otherSize, otherBox.max);
|
// glm_vec2_add(otherBox.min, otherSize, otherBox.max);
|
||||||
|
|
||||||
physicsBoxCheckBox(interactBox, otherBox, &result);
|
// physicsBoxCheckBox(interactBox, otherBox, &result);
|
||||||
if(!result.hit) continue;
|
// if(!result.hit) continue;
|
||||||
|
|
||||||
printf("Interacted with entity at (%.2f, %.2f)\n", start->position[0], start->position[1]);
|
// printf("Interacted with entity at (%.2f, %.2f)\n", start->position[0], start->position[1]);
|
||||||
break;
|
// break;
|
||||||
} while(++start != end);
|
// } while(++start != end);
|
||||||
}
|
}
|
@@ -14,11 +14,23 @@
|
|||||||
#include "rpg/rpgcamera.h"
|
#include "rpg/rpgcamera.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
|
|
||||||
#define TILE_SIZE 1
|
#define TILE_SIZE 16
|
||||||
|
|
||||||
errorret_t sceneMapInit(scenedata_t *data) {
|
errorret_t sceneMapInit(scenedata_t *data) {
|
||||||
cameraInitPerspective(&data->sceneMap.camera);
|
cameraInitPerspective(&data->sceneMap.camera);
|
||||||
data->sceneMap.camera.projType = CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED;
|
data->sceneMap.camera.projType = CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED;
|
||||||
|
data->sceneMap.camera.viewType = CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT;
|
||||||
|
glm_vec3_zero(data->sceneMap.camera.lookatPixelPerfect.offset);
|
||||||
|
data->sceneMap.camera.lookatPixelPerfect.offset[2] = 32.0f;
|
||||||
|
glm_vec3_copy(
|
||||||
|
(vec3){ 0.0f, 0.0f, 0.0f },
|
||||||
|
data->sceneMap.camera.lookatPixelPerfect.target
|
||||||
|
);
|
||||||
|
glm_vec3_copy(
|
||||||
|
(vec3){ 0.0f, 1.0f, 0.0f },
|
||||||
|
data->sceneMap.camera.lookatPixelPerfect.up
|
||||||
|
);
|
||||||
|
data->sceneMap.camera.lookatPixelPerfect.pixelsPerUnit = 1.0f;
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
@@ -27,49 +39,20 @@ void sceneMapUpdate(scenedata_t *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sceneMapRender(scenedata_t *data) {
|
void sceneMapRender(scenedata_t *data) {
|
||||||
|
|
||||||
// Look at target.
|
// Look at target.
|
||||||
glm_vec3_scale(
|
glm_vec3_scale(
|
||||||
RPG_CAMERA.position,
|
RPG_CAMERA.position,
|
||||||
TILE_SIZE,
|
TILE_SIZE,
|
||||||
data->sceneMap.camera.lookat.target
|
data->sceneMap.camera.lookatPixelPerfect.target
|
||||||
);
|
);
|
||||||
|
|
||||||
// Center within tile
|
// Center within tile
|
||||||
glm_vec3_add(
|
glm_vec3_add(
|
||||||
data->sceneMap.camera.lookat.target,
|
data->sceneMap.camera.lookatPixelPerfect.target,
|
||||||
(vec3){TILE_SIZE / 2.0f, TILE_SIZE / 2.0f, TILE_SIZE / 2.0f },
|
(vec3){TILE_SIZE / 2.0f, TILE_SIZE / 2.0f, TILE_SIZE / 2.0f },
|
||||||
data->sceneMap.camera.lookat.target
|
data->sceneMap.camera.lookatPixelPerfect.target
|
||||||
);
|
);
|
||||||
|
|
||||||
// Apply pixel perfect offset and camera offset
|
|
||||||
const float_t camOffset = 0.01f;
|
|
||||||
const float_t pixelPerfectOffset = tanf(
|
|
||||||
data->sceneMap.camera.perspective.fov / 2.0f
|
|
||||||
) * ((float_t)SCREEN.height / 2.0f);
|
|
||||||
|
|
||||||
glm_vec3_copy((vec3){
|
|
||||||
data->sceneMap.camera.lookat.target[0],
|
|
||||||
data->sceneMap.camera.lookat.target[1] + camOffset,
|
|
||||||
data->sceneMap.camera.lookat.target[2] + pixelPerfectOffset
|
|
||||||
}, data->sceneMap.camera.lookat.position);
|
|
||||||
|
|
||||||
// TESTING ONLY
|
|
||||||
camera_t backup = data->sceneMap.camera;
|
|
||||||
cameraInitOrthographic(&data->sceneMap.camera);
|
|
||||||
data->sceneMap.camera.projType = CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC;
|
|
||||||
glm_vec3_copy((vec3){
|
|
||||||
RPG_CAMERA.position[0] * TILE_SIZE,
|
|
||||||
RPG_CAMERA.position[1] * TILE_SIZE,
|
|
||||||
10.0f
|
|
||||||
}, data->sceneMap.camera._2d.position);
|
|
||||||
data->sceneMap.camera.orthographic.left = 0.0f;
|
|
||||||
data->sceneMap.camera.orthographic.right = SCREEN.width;
|
|
||||||
data->sceneMap.camera.orthographic.top = 0.0f;
|
|
||||||
data->sceneMap.camera.orthographic.bottom = SCREEN.height;
|
|
||||||
data->sceneMap.camera.nearClip = -100.0f;
|
|
||||||
data->sceneMap.camera.farClip = 100.0f;
|
|
||||||
|
|
||||||
// Push camera
|
// Push camera
|
||||||
cameraPushMatrix(&data->sceneMap.camera);
|
cameraPushMatrix(&data->sceneMap.camera);
|
||||||
|
|
||||||
@@ -82,9 +65,6 @@ void sceneMapRender(scenedata_t *data) {
|
|||||||
|
|
||||||
// Finished, pop back camera.
|
// Finished, pop back camera.
|
||||||
cameraPopMatrix();
|
cameraPopMatrix();
|
||||||
|
|
||||||
//END TESTING
|
|
||||||
data->sceneMap.camera = backup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sceneMapRenderEntity(entity_t *entity) {
|
void sceneMapRenderEntity(entity_t *entity) {
|
||||||
@@ -93,8 +73,7 @@ void sceneMapRenderEntity(entity_t *entity) {
|
|||||||
if(entity->type == ENTITY_TYPE_NULL) return;
|
if(entity->type == ENTITY_TYPE_NULL) return;
|
||||||
|
|
||||||
vec3 posMin, posMax;
|
vec3 posMin, posMax;
|
||||||
// glm_vec3_scale(entity->position, TILE_SIZE, posMin);
|
glm_vec3_scale(entity->position, TILE_SIZE, posMin);
|
||||||
posMin[0] = 1, posMin[1] = 1, posMin[2] = 0;
|
|
||||||
glm_vec3_add(posMin, (vec3){TILE_SIZE, TILE_SIZE, TILE_SIZE }, posMax);
|
glm_vec3_add(posMin, (vec3){TILE_SIZE, TILE_SIZE, TILE_SIZE }, posMax);
|
||||||
|
|
||||||
vec2 uv0 = { 0.0f, 0.0f };
|
vec2 uv0 = { 0.0f, 0.0f };
|
||||||
|
@@ -135,12 +135,14 @@ def processTileset(asset):
|
|||||||
data += f" .image = {json.dumps(tilesetData['image']['imagePath'])},\n"
|
data += f" .image = {json.dumps(tilesetData['image']['imagePath'])},\n"
|
||||||
data += f"}};\n"
|
data += f"}};\n"
|
||||||
|
|
||||||
|
|
||||||
# Write Header
|
# Write Header
|
||||||
outputFile = os.path.join(args.headers_dir, "display", "tileset", f"tileset_{tilesetName}.h")
|
outputFile = os.path.join(args.headers_dir, "display", "tileset", f"tileset_{tilesetName}.h")
|
||||||
os.makedirs(os.path.dirname(outputFile), exist_ok=True)
|
os.makedirs(os.path.dirname(outputFile), exist_ok=True)
|
||||||
with open(outputFile, 'w') as f:
|
with open(outputFile, 'w') as f:
|
||||||
f.write(data)
|
f.write(data)
|
||||||
|
|
||||||
|
print(f"Write header for tileset: {outputFile}")
|
||||||
|
|
||||||
tileset = {
|
tileset = {
|
||||||
"files": [],
|
"files": [],
|
||||||
|
Reference in New Issue
Block a user