demo buggy heightmap
This commit is contained in:
@@ -51,7 +51,9 @@ void GameState::update() {
|
||||
auto cameraInfo = player.getCameraInfo();
|
||||
engine->renderer.beginFrame(cameraInfo);
|
||||
|
||||
player.update();
|
||||
float terrainHeight = terrain.getHeightOffset(player.getPosition());
|
||||
player.update(terrainHeight);
|
||||
|
||||
dbgObj.setPosition(*cameraInfo.looksAt);
|
||||
|
||||
renderer.clear();
|
||||
|
||||
@@ -21,7 +21,7 @@ Camera::Camera(Pad* t_pad) : lookAt(0.0F), position(0.0F), pad(t_pad) {
|
||||
|
||||
Camera::~Camera() {}
|
||||
|
||||
void Camera::update(const Vec4& playerPosition) {
|
||||
void Camera::update(const Vec4& playerPosition, const float& terrainHeight) {
|
||||
const float rotationOffset = 0.03F;
|
||||
const float heightOffset = 0.5F;
|
||||
|
||||
@@ -40,7 +40,7 @@ void Camera::update(const Vec4& playerPosition) {
|
||||
}
|
||||
|
||||
unitCircle.x = (sin(circleRotation) * lengthFromOrigin);
|
||||
unitCircle.y = height + playerPosition.y;
|
||||
unitCircle.y = height + playerPosition.y + terrainHeight;
|
||||
unitCircle.z = (cos(circleRotation) * lengthFromOrigin);
|
||||
|
||||
lookAt = unitCircle + playerPosition;
|
||||
|
||||
@@ -18,7 +18,7 @@ Player::Player(Engine* engine)
|
||||
camera(&engine->pad) {
|
||||
staticPairs.push_back(new RendererStaticPair{weapon.mesh, weapon.options});
|
||||
pad = &engine->pad;
|
||||
position = Vec4(3.0F, 15.0F, 0.0F);
|
||||
position = Vec4(3.0F, 50.0F, 0.0F);
|
||||
camera.lookAt = Vec4(0.0F, 0.0F, -30.0F);
|
||||
speed = 2.0F;
|
||||
}
|
||||
@@ -32,13 +32,13 @@ Player::~Player() {
|
||||
}
|
||||
}
|
||||
|
||||
void Player::update() {
|
||||
handlePlayerPosition();
|
||||
camera.update(position);
|
||||
void Player::update(const float& terrainHeight) {
|
||||
handlePlayerPosition(terrainHeight);
|
||||
camera.update(position, terrainHeight);
|
||||
weapon.update();
|
||||
}
|
||||
|
||||
void Player::handlePlayerPosition() {
|
||||
void Player::handlePlayerPosition(const float& terrainHeight) {
|
||||
const auto& leftJoy = pad->getLeftJoyPad();
|
||||
|
||||
auto normalizedCamera = Vec4(camera.unitCircle);
|
||||
@@ -46,6 +46,7 @@ void Player::handlePlayerPosition() {
|
||||
normalizedCamera *= speed;
|
||||
|
||||
Vec4 nextPosition(position);
|
||||
nextPosition.y = terrainHeight;
|
||||
|
||||
if (leftJoy.v <= 100) {
|
||||
nextPosition.x += normalizedCamera.x;
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#include "states/game/terrain/heightmap.hpp"
|
||||
#include "file/file_utils.hpp"
|
||||
#include "debug/debug.hpp"
|
||||
|
||||
using Tyra::FileUtils;
|
||||
using Tyra::PngLoader;
|
||||
using Tyra::PngPixel3;
|
||||
using Tyra::Vec4;
|
||||
|
||||
namespace Demo {
|
||||
|
||||
Heightmap::Heightmap(const float& t_minHeight, const float& t_maxHeight,
|
||||
const Vec4& t_leftUp, const Vec4& t_rightDown)
|
||||
: minHeight(t_minHeight),
|
||||
maxHeight(t_maxHeight),
|
||||
leftUp(t_leftUp),
|
||||
rightDown(t_rightDown) {
|
||||
PngLoader loader;
|
||||
auto* data =
|
||||
loader.load(FileUtils::fromCwd("game/models/terrain/heightmap.png"));
|
||||
|
||||
allocateMap(data->data, data->width, data->height);
|
||||
|
||||
delete data;
|
||||
}
|
||||
|
||||
Heightmap::~Heightmap() {
|
||||
if (map) {
|
||||
for (int i = 0; i < mapHeight; i++) {
|
||||
delete[] map[i];
|
||||
}
|
||||
delete[] map;
|
||||
}
|
||||
}
|
||||
|
||||
const float& Heightmap::getHeightOffset(const Vec4& playerPosition) {
|
||||
float widthPercentage = getWidthPercentage(playerPosition);
|
||||
float heightPercentage = getHeightPercentage(playerPosition);
|
||||
|
||||
auto x = static_cast<s16>(widthPercentage * mapWidth);
|
||||
auto y = static_cast<s16>(heightPercentage * mapHeight);
|
||||
|
||||
TYRA_ASSERT(x >= 0 && x < mapWidth, "x is out of range");
|
||||
TYRA_ASSERT(y >= 0 && y < mapHeight, "y is out of range");
|
||||
|
||||
return map[x][y];
|
||||
}
|
||||
|
||||
float Heightmap::getWidthPercentage(const Vec4& playerPosition) {
|
||||
return (playerPosition.x - leftUp.x) / (rightDown.x - leftUp.x);
|
||||
}
|
||||
|
||||
float Heightmap::getHeightPercentage(const Vec4& playerPosition) {
|
||||
return (playerPosition.z - leftUp.z) / (rightDown.z - leftUp.z);
|
||||
}
|
||||
|
||||
void Heightmap::allocateMap(const unsigned char* data, const int& width,
|
||||
const int& height) {
|
||||
auto* pixels = (struct PngPixel3*)data;
|
||||
|
||||
u8 min = pixels[0].r; // in grayscale every r,g,b is the same
|
||||
u8 max = pixels[0].r;
|
||||
|
||||
// Get min and max
|
||||
for (int i = 0; i < width * height; i++) {
|
||||
const auto& value = pixels[i].r;
|
||||
if (value < min) {
|
||||
min = value;
|
||||
}
|
||||
if (value > max) {
|
||||
max = value;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate
|
||||
mapWidth = width;
|
||||
mapHeight = height;
|
||||
map = new float*[width];
|
||||
for (int i = 0; i < width; i++) {
|
||||
map[i] = new float[height];
|
||||
}
|
||||
|
||||
// Fill
|
||||
int k = 0;
|
||||
for (int j = 0; j < height; j++) {
|
||||
for (int i = 0; i < width; i++) {
|
||||
map[i][j] = getGameHeight(pixels[k++].r, min, max);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float Heightmap::getGameHeight(const u8& inputColor, const u8& minColor,
|
||||
const u8& maxColor) {
|
||||
const float mapRange = maxColor - minColor;
|
||||
const float gameRange = maxHeight - minHeight;
|
||||
|
||||
return (inputColor - minColor) / mapRange * gameRange + minHeight;
|
||||
}
|
||||
|
||||
} // namespace Demo
|
||||
@@ -16,8 +16,12 @@ using Tyra::FileUtils;
|
||||
using Tyra::TyrobjLoader;
|
||||
|
||||
namespace Demo {
|
||||
|
||||
Terrain::Terrain(TextureRepository* repo) {
|
||||
Terrain::Terrain(TextureRepository* repo)
|
||||
: heightmap(-5.0F, // Min height
|
||||
70.0F, // Max height
|
||||
Vec4(-196.6F, 0.0F, -412.0F, 1.0F), // Left up
|
||||
Vec4(286.0F, 0.0F, 443.3F, 1.0F) // Right down
|
||||
) {
|
||||
TyrobjLoader loader;
|
||||
auto* data = loader.load(
|
||||
FileUtils::fromCwd("game/models/terrain/terrain.obj"), 1, 25.0F, true);
|
||||
@@ -35,14 +39,8 @@ Terrain::Terrain(TextureRepository* repo) {
|
||||
pair = new RendererStaticPair{mesh, options};
|
||||
}
|
||||
|
||||
// float testRotation = 0.0F;
|
||||
|
||||
void Terrain::update() {
|
||||
// testRotation += 0.001F;
|
||||
mesh->rotation.identity();
|
||||
mesh->rotation.rotateZ(0.1F);
|
||||
mesh->rotation.rotateY(-4.3F);
|
||||
// TYRA_LOG(testRotation);
|
||||
float Terrain::getHeightOffset(const Vec4& playerPosition) {
|
||||
return heightmap.getHeightOffset(playerPosition);
|
||||
}
|
||||
|
||||
Terrain::~Terrain() {
|
||||
|
||||
Reference in New Issue
Block a user