demo buggy heightmap

This commit is contained in:
h4570
2022-08-01 10:04:21 +02:00
parent 47c323ec9e
commit 34b2956c08
12 changed files with 194 additions and 33 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ class Camera {
CameraInfo3D getCameraInfo() { return CameraInfo3D(&position, &lookAt); }
void update(const Vec4& playerPosition);
void update(const Vec4& playerPosition, const float& terrainHeight);
private:
float circleRotation, lengthFromOrigin, height;
+4 -3
View File
@@ -27,17 +27,18 @@ class Player {
Player(Engine* engine);
~Player();
const Vec4& getPosition() const { return position; }
CameraInfo3D getCameraInfo() { return camera.getCameraInfo(); }
std::vector<RendererStaticPair*> staticPairs;
std::vector<RendererDynamicPair*> dynamicPairs;
void update();
void update(const float& terrainHeight);
private:
void handlePlayerPosition();
void handlePlayerPosition(const float& terrainHeight);
float speed;
float speed;
Pad* pad;
Vec4 position;
Weapon weapon;
@@ -0,0 +1,42 @@
/*
# ______ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licenced under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "math/vec4.hpp"
#include "loaders/texture/png_loader.hpp"
using Tyra::Vec4;
namespace Demo {
class Heightmap {
public:
Heightmap(const float& minHeight, const float& maxHeight, const Vec4& leftUp,
const Vec4& rightDown);
~Heightmap();
const float& getHeightOffset(const Vec4& playerPosition);
float** map;
s16 mapWidth, mapHeight;
float minHeight, maxHeight;
Vec4 leftUp, rightDown;
private:
float getWidthPercentage(const Vec4& playerPosition);
float getHeightPercentage(const Vec4& playerPosition);
void allocateMap(const unsigned char* data, const int& width,
const int& height);
float getGameHeight(const u8& inputColor, const u8& minColor,
const u8& maxColor);
};
} // namespace Demo
+4 -1
View File
@@ -14,10 +14,12 @@
#include <renderer/3d/pipeline/static/stapip_options.hpp>
#include "states/game/renderer/renderer_static_pair.hpp"
#include <renderer/renderer.hpp>
#include "./heightmap.hpp"
using Tyra::StaPipOptions;
using Tyra::StaticMesh;
using Tyra::TextureRepository;
using Tyra::Vec4;
namespace Demo {
@@ -26,11 +28,12 @@ class Terrain {
Terrain(TextureRepository* repo);
~Terrain();
Heightmap heightmap;
StaticMesh* mesh;
StaPipOptions* options;
RendererStaticPair* pair;
void update();
float getHeightOffset(const Vec4& playerPosition);
private:
void allocateOptions();
+3 -1
View File
@@ -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();
+2 -2
View File
@@ -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;
+6 -5
View File
@@ -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;
+110
View File
@@ -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
+8 -10
View File
@@ -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() {